summaryrefslogtreecommitdiffstats
path: root/src/VBox/Additions/common/crOpenGL
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 03:01:46 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 03:01:46 +0000
commitf8fe689a81f906d1b91bb3220acde2a4ecb14c5b (patch)
tree26484e9d7e2c67806c2d1760196ff01aaa858e8c /src/VBox/Additions/common/crOpenGL
parentInitial commit. (diff)
downloadvirtualbox-f8fe689a81f906d1b91bb3220acde2a4ecb14c5b.tar.xz
virtualbox-f8fe689a81f906d1b91bb3220acde2a4ecb14c5b.zip
Adding upstream version 6.0.4-dfsg.upstream/6.0.4-dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Additions/common/crOpenGL')
-rw-r--r--src/VBox/Additions/common/crOpenGL/.scm-settings62
-rw-r--r--src/VBox/Additions/common/crOpenGL/AIX_exports.py11
-rw-r--r--src/VBox/Additions/common/crOpenGL/COPYRIGHT.LLNL61
-rw-r--r--src/VBox/Additions/common/crOpenGL/COPYRIGHT.REDHAT29
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/DD_glc.py139
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/DD_glh.py136
-rw-r--r--src/VBox/Additions/common/crOpenGL/Darwin_exports.py12
-rw-r--r--src/VBox/Additions/common/crOpenGL/FreeBSD_exports.py11
-rw-r--r--src/VBox/Additions/common/crOpenGL/IRIX64_exports.py11
-rw-r--r--src/VBox/Additions/common/crOpenGL/LICENSE32
-rw-r--r--src/VBox/Additions/common/crOpenGL/Linux_exports.py10
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/Linux_i386_exports.py96
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/Linux_i386_exports_dri.py96
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/Linux_i386_glxapi_exports.py109
-rw-r--r--src/VBox/Additions/common/crOpenGL/Makefile.kmk734
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/NULLfuncs.py58
-rw-r--r--src/VBox/Additions/common/crOpenGL/OSF1_exports.py11
-rw-r--r--src/VBox/Additions/common/crOpenGL/SunOS_exports.py11
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/SunOS_i386_exports.py98
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/SunOS_i386_exports_dri.py98
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/SunOS_i386_glxapi_exports.py103
-rw-r--r--src/VBox/Additions/common/crOpenGL/VBoxCROGL.rc70
-rw-r--r--src/VBox/Additions/common/crOpenGL/VBoxICDList.h385
-rw-r--r--src/VBox/Additions/common/crOpenGL/alias_exports.py168
-rw-r--r--src/VBox/Additions/common/crOpenGL/array/Makefile.kup0
-rw-r--r--src/VBox/Additions/common/crOpenGL/array/arrayspu.c944
-rw-r--r--src/VBox/Additions/common/crOpenGL/array/arrayspu.def6
-rw-r--r--src/VBox/Additions/common/crOpenGL/array/arrayspu.h46
-rw-r--r--src/VBox/Additions/common/crOpenGL/array/arrayspu.rc69
-rw-r--r--src/VBox/Additions/common/crOpenGL/array/arrayspu_config.c27
-rw-r--r--src/VBox/Additions/common/crOpenGL/array/arrayspu_init.c86
-rw-r--r--src/VBox/Additions/common/crOpenGL/context.c1463
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/cr_gl.py65
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/defs.py505
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/defs64.py485
-rw-r--r--src/VBox/Additions/common/crOpenGL/dri_drv.c1012
-rw-r--r--src/VBox/Additions/common/crOpenGL/dri_drv.h32
-rw-r--r--src/VBox/Additions/common/crOpenGL/dri_glx.h165
-rw-r--r--src/VBox/Additions/common/crOpenGL/dri_util.c1117
-rw-r--r--src/VBox/Additions/common/crOpenGL/drirenderbuffer.c215
-rw-r--r--src/VBox/Additions/common/crOpenGL/egl.c967
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/entrypoints.py180
-rw-r--r--src/VBox/Additions/common/crOpenGL/fakedri_drv.c878
-rw-r--r--src/VBox/Additions/common/crOpenGL/fakedri_drv.h123
-rw-r--r--src/VBox/Additions/common/crOpenGL/fakedri_glfuncsList.h730
-rw-r--r--src/VBox/Additions/common/crOpenGL/fakedri_glxfuncsList.h93
-rw-r--r--src/VBox/Additions/common/crOpenGL/feedback/Makefile.kup0
-rw-r--r--src/VBox/Additions/common/crOpenGL/feedback/feedback.def6
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/feedback/feedback.py270
-rw-r--r--src/VBox/Additions/common/crOpenGL/feedback/feedback_context.c131
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/feedback/feedback_funcs.py40
-rw-r--r--src/VBox/Additions/common/crOpenGL/feedback/feedback_special64
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/feedback/feedback_state.py34
-rw-r--r--src/VBox/Additions/common/crOpenGL/feedback/feedback_state_special66
-rw-r--r--src/VBox/Additions/common/crOpenGL/feedback/feedbackspu.h58
-rw-r--r--src/VBox/Additions/common/crOpenGL/feedback/feedbackspu.rc69
-rw-r--r--src/VBox/Additions/common/crOpenGL/feedback/feedbackspu_config.c44
-rw-r--r--src/VBox/Additions/common/crOpenGL/feedback/feedbackspu_init.c86
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/feedback/feedbackspu_proto.py35
-rw-r--r--src/VBox/Additions/common/crOpenGL/feedback/select_special56
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/getprocaddress.py125
-rw-r--r--src/VBox/Additions/common/crOpenGL/glx.c2113
-rw-r--r--src/VBox/Additions/common/crOpenGL/glx_c_exports.c375
-rw-r--r--src/VBox/Additions/common/crOpenGL/glx_proto.h149
-rw-r--r--src/VBox/Additions/common/crOpenGL/icd_drv.c398
-rw-r--r--src/VBox/Additions/common/crOpenGL/icd_drv.h55
-rw-r--r--src/VBox/Additions/common/crOpenGL/load.c1526
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/Makefile.kup0
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/pack.def6
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/pack/pack.py57
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu.h185
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu.rc69
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/pack/packspu_beginend.py177
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_bufferobject.c160
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_client.c910
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_config.c60
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_context.c617
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/pack/packspu_flush.py42
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_flush_special9
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_framebuffer.c143
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/pack/packspu_get.py250
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_getshaders.c214
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_getstring.c211
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_glsl.c275
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_init.c152
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_misc.c856
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_net.c284
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_pixel.c727
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/pack/packspu_proto.py50
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_special138
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_swapbuf.c102
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_texture.c70
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_unimplemented_special4
-rw-r--r--src/VBox/Additions/common/crOpenGL/pack/packspu_vertex_special28
-rw-r--r--src/VBox/Additions/common/crOpenGL/passthrough/Makefile.kup0
-rw-r--r--src/VBox/Additions/common/crOpenGL/passthrough/passthrough.def6
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/passthrough/passthrough.py40
-rw-r--r--src/VBox/Additions/common/crOpenGL/passthrough/passthroughspu.h21
-rw-r--r--src/VBox/Additions/common/crOpenGL/passthrough/passthroughspu.rc69
-rw-r--r--src/VBox/Additions/common/crOpenGL/passthrough/passthroughspu_init.c64
-rw-r--r--src/VBox/Additions/common/crOpenGL/stub.c548
-rw-r--r--src/VBox/Additions/common/crOpenGL/stub.h370
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/stub_common.py282
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/tsfuncs.py47
-rw-r--r--src/VBox/Additions/common/crOpenGL/utils.c876
-rw-r--r--src/VBox/Additions/common/crOpenGL/vboxdri_drv.c694
-rw-r--r--src/VBox/Additions/common/crOpenGL/wgl.c1015
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/windows_exports.py98
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/windows_getprocaddress.py171
-rwxr-xr-xsrc/VBox/Additions/common/crOpenGL/windows_i386_exports.py95
-rw-r--r--src/VBox/Additions/common/crOpenGL/xfont.c244
111 files changed, 27895 insertions, 0 deletions
diff --git a/src/VBox/Additions/common/crOpenGL/.scm-settings b/src/VBox/Additions/common/crOpenGL/.scm-settings
new file mode 100644
index 00000000..e6362722
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/.scm-settings
@@ -0,0 +1,62 @@
+# $Id: .scm-settings $
+## @file
+# Source code massager settings for common/crOpenGL.
+#
+
+#
+# Copyright (C) 2010-2019 Oracle Corporation
+#
+# This file is part of VirtualBox Open Source Edition (OSE), as
+# available from http://www.virtualbox.org. This file is free software;
+# you can redistribute it and/or modify it under the terms of the GNU
+# General Public License (GPL) as published by the Free Software
+# Foundation, in version 2 as it comes in the "COPYING" file of the
+# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+#
+
+# Much of this is externally licensed, but not all, sigh.
+--external-copyright --no-convert-tabs
+
+/array/arrayspu.rc: --no-external-copyright --convert-tabs
+
+/feedback/feedbackspu.rc: --no-external-copyright --convert-tabs
+/feedback/feedback_context.c: --no-external-copyright --convert-tabs
+
+/pack/packspu.rc: --no-external-copyright --convert-tabs
+/pack/packspu_framebuffer.c: --no-external-copyright --convert-tabs
+/pack/packspu_getshaders.c: --no-external-copyright --convert-tabs
+/pack/packspu_glsl.c: --no-external-copyright --convert-tabs
+/pack/packspu_texture.c: --no-external-copyright --convert-tabs
+
+/passthrough/passthroughspu.rc: --no-external-copyright --convert-tabs
+
+/.scm-settings: --no-external-copyright --convert-tabs
+/dri_drv.c: --no-external-copyright --convert-tabs
+/dri_drv.h: --no-external-copyright --convert-tabs
+/dri_glx.h: --no-external-copyright --convert-tabs
+/egl.c: --no-external-copyright --convert-tabs
+/fakedri_drv.c: --no-external-copyright --convert-tabs
+/fakedri_drv.h: --no-external-copyright --convert-tabs
+/fakedri_glfuncsList.h: --no-external-copyright --convert-tabs --no-fix-header-guards
+/fakedri_glxfuncsList.h: --no-external-copyright --convert-tabs --no-fix-header-guards
+/glx.c: --no-external-copyright --convert-tabs
+/glx_c_exports.c: --no-external-copyright --convert-tabs
+/glx_proto.h: --no-external-copyright --convert-tabs
+/icd_drv.c: --no-external-copyright --convert-tabs
+/icd_drv.h: --no-external-copyright --convert-tabs
+/Linux_i386_glxapi_exports.py: --no-external-copyright --convert-tabs
+/Makefile.kmk: --no-external-copyright --convert-tabs
+/SunOS_i386_exports.py: --no-external-copyright --convert-tabs
+/SunOS_i386_exports_dri.py: --no-external-copyright --convert-tabs
+/SunOS_i386_glxapi_exports.py: --no-external-copyright --convert-tabs
+/VBoxCROGL.rc: --no-external-copyright --convert-tabs
+/VBoxICDList.h: --no-external-copyright --no-fix-header-guards
+
+*_special: --treat-as Makefile
+
+# Ignore some stuff.
+--filter-out-files /COPYRIGHT.LLNL
+--filter-out-files /COPYRIGHT.REDHAT
+--filter-out-files /LICENSE
+
diff --git a/src/VBox/Additions/common/crOpenGL/AIX_exports.py b/src/VBox/Additions/common/crOpenGL/AIX_exports.py
new file mode 100644
index 00000000..2f55db33
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/AIX_exports.py
@@ -0,0 +1,11 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+import entrypoints
+
+hacks = ["TexImage3D", "MultiDrawElementsEXT" ]
+
+entrypoints.GenerateEntrypoints(hacks)
+
diff --git a/src/VBox/Additions/common/crOpenGL/COPYRIGHT.LLNL b/src/VBox/Additions/common/crOpenGL/COPYRIGHT.LLNL
new file mode 100644
index 00000000..5fc1a271
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/COPYRIGHT.LLNL
@@ -0,0 +1,61 @@
+This Chromium distribution contains information and code which is
+covered under the following notice:
+
+Copyright (c) 2002, The Regents of the University of California.
+Produced at the Lawrence Livermore National Laboratory
+For details, contact: Randall Frank (rjfrank@llnl.gov).
+UCRL-CODE-2002-058
+All rights reserved.
+
+This file is part of Chromium. For details, see accompanying
+documentation.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this
+list of conditions and the disclaimer below.
+
+Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the disclaimer (as noted below) in the
+documentation and/or other materials provided with the distribution.
+
+Neither the name of the UC/LLNL nor the names of its contributors may be
+used to endorse or promote products derived from this software without
+specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF
+CALIFORNIA, THE U.S. DEPARTMENT OF ENERGY OR CONTRIBUTORS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+Additional BSD Notice
+
+1. This notice is required to be provided under our contract with the U.S.
+ Department of Energy (DOE). This work was produced at the University of
+ California, Lawrence Livermore National Laboratory under Contract No.
+ W-7405-ENG-48 with the DOE.
+
+2. Neither the United States Government nor the University of California
+ nor any of their employees, makes any warranty, express or implied, or
+ assumes any liability or responsibility for the accuracy, completeness,
+ or usefulness of any information, apparatus, product, or process
+ disclosed, or represents that its use would not infringe privately-owned
+ rights.
+
+3. Also, reference herein to any specific commercial products, process, or
+ services by trade name, trademark, manufacturer or otherwise does not
+ necessarily constitute or imply its endorsement, recommendation, or
+ favoring by the United States Government or the University of
+ California. The views and opinions of authors expressed herein do not
+ necessarily state or reflect those of the United States Government or
+ the University of California, and shall not be used for advertising or
+ product endorsement purposes.
diff --git a/src/VBox/Additions/common/crOpenGL/COPYRIGHT.REDHAT b/src/VBox/Additions/common/crOpenGL/COPYRIGHT.REDHAT
new file mode 100644
index 00000000..7812243e
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/COPYRIGHT.REDHAT
@@ -0,0 +1,29 @@
+This Chromium distribution contains information and code which is
+covered under the following notice:
+
+/*
+ * Copyright 2001,2002 Red Hat Inc., Durham, North Carolina.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation on the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
diff --git a/src/VBox/Additions/common/crOpenGL/DD_glc.py b/src/VBox/Additions/common/crOpenGL/DD_glc.py
new file mode 100755
index 00000000..33aee4da
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/DD_glc.py
@@ -0,0 +1,139 @@
+from __future__ import print_function
+print("""
+/** @file
+ * VBox OpenGL chromium functions header
+ */
+
+/*
+ * Copyright (C) 2009-2016 """ """Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+""")
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+import sys
+
+import apiutil
+
+apiutil.CopyrightC()
+
+print("""
+/* DO NOT EDIT - THIS FILE GENERATED BY THE DD_gl.py SCRIPT */
+
+#include "chromium.h"
+#include "cr_string.h"
+#include "cr_version.h"
+#include "stub.h"
+#include "dri_drv.h"
+#include "cr_gl.h"
+""")
+
+commoncall_special = [
+ "ArrayElement",
+ "Begin",
+ "CallList",
+ "CallLists",
+ "Color3f",
+ "Color3fv",
+ "Color4f",
+ "Color4fv",
+ "EdgeFlag",
+ "End",
+ "EvalCoord1f",
+ "EvalCoord1fv",
+ "EvalCoord2f",
+ "EvalCoord2fv",
+ "EvalPoint1",
+ "EvalPoint2",
+ "FogCoordfEXT",
+ "FogCoordfvEXT",
+ "Indexf",
+ "Indexfv",
+ "Materialfv",
+ "MultiTexCoord1fARB",
+ "MultiTexCoord1fvARB",
+ "MultiTexCoord2fARB",
+ "MultiTexCoord2fvARB",
+ "MultiTexCoord3fARB",
+ "MultiTexCoord3fvARB",
+ "MultiTexCoord4fARB",
+ "MultiTexCoord4fvARB",
+ "Normal3f",
+ "Normal3fv",
+ "SecondaryColor3fEXT",
+ "SecondaryColor3fvEXT",
+ "TexCoord1f",
+ "TexCoord1fv",
+ "TexCoord2f",
+ "TexCoord2fv",
+ "TexCoord3f",
+ "TexCoord3fv",
+ "TexCoord4f",
+ "TexCoord4fv",
+ "Vertex2f",
+ "Vertex2fv",
+ "Vertex3f",
+ "Vertex3fv",
+ "Vertex4f",
+ "Vertex4fv",
+ "VertexAttrib1fNV",
+ "VertexAttrib1fvNV",
+ "VertexAttrib2fNV",
+ "VertexAttrib2fvNV",
+ "VertexAttrib3fNV",
+ "VertexAttrib3fvNV",
+ "VertexAttrib4fNV",
+ "VertexAttrib4fvNV",
+ "VertexAttrib1fARB",
+ "VertexAttrib1fvARB",
+ "VertexAttrib2fARB",
+ "VertexAttrib2fvARB",
+ "VertexAttrib3fARB",
+ "VertexAttrib3fvARB",
+ "VertexAttrib4fARB",
+ "VertexAttrib4fvARB",
+ "EvalMesh1",
+ "EvalMesh2",
+ "Rectf",
+ "DrawArrays",
+ "DrawElements",
+ "DrawRangeElements"
+]
+
+keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+for func_name in keys:
+ if "Chromium" == apiutil.Category(func_name):
+ continue
+ if func_name == "BoundsInfoCR":
+ continue
+
+ return_type = apiutil.ReturnType(func_name)
+ params = apiutil.Parameters(func_name)
+
+ if func_name in commoncall_special:
+ print("%s vboxDD_gl%s(%s)" % (return_type, func_name, apiutil.MakeDeclarationString(params) ))
+ else:
+ if apiutil.MakeDeclarationString(params)=="void":
+ print("%s vboxDD_gl%s(GLcontext *ctx)" % (return_type, func_name ))
+ else:
+ print("%s vboxDD_gl%s(GLcontext *ctx, %s)" % (return_type, func_name, apiutil.MakeDeclarationString(params) ))
+ print("{")
+
+ if return_type != "void":
+ print("\treturn ", end=' ')
+
+ print("\tcr_gl%s(%s);" % (func_name, apiutil.MakeCallString(params)))
+ print("}")
+ print("")
+
diff --git a/src/VBox/Additions/common/crOpenGL/DD_glh.py b/src/VBox/Additions/common/crOpenGL/DD_glh.py
new file mode 100755
index 00000000..38d9ba60
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/DD_glh.py
@@ -0,0 +1,136 @@
+from __future__ import print_function
+print("""
+/** @file
+ * VBox OpenGL chromium functions header
+ */
+
+/*
+ * Copyright (C) 2009-2016 """ """Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+""")
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+import sys
+
+import apiutil
+
+apiutil.CopyrightC()
+
+print("""
+/* DO NOT EDIT - THIS FILE GENERATED BY THE DD_gl.py SCRIPT */
+#ifndef __DD_GL_H__
+#define __DD_GL_H__
+
+#include "chromium.h"
+#include "cr_string.h"
+#include "cr_version.h"
+#include "stub.h"
+
+""")
+
+commoncall_special = [
+ "ArrayElement",
+ "Begin",
+ "CallList",
+ "CallLists",
+ "Color3f",
+ "Color3fv",
+ "Color4f",
+ "Color4fv",
+ "EdgeFlag",
+ "End",
+ "EvalCoord1f",
+ "EvalCoord1fv",
+ "EvalCoord2f",
+ "EvalCoord2fv",
+ "EvalPoint1",
+ "EvalPoint2",
+ "FogCoordfEXT",
+ "FogCoordfvEXT",
+ "Indexf",
+ "Indexfv",
+ "Materialfv",
+ "MultiTexCoord1fARB",
+ "MultiTexCoord1fvARB",
+ "MultiTexCoord2fARB",
+ "MultiTexCoord2fvARB",
+ "MultiTexCoord3fARB",
+ "MultiTexCoord3fvARB",
+ "MultiTexCoord4fARB",
+ "MultiTexCoord4fvARB",
+ "Normal3f",
+ "Normal3fv",
+ "SecondaryColor3fEXT",
+ "SecondaryColor3fvEXT",
+ "TexCoord1f",
+ "TexCoord1fv",
+ "TexCoord2f",
+ "TexCoord2fv",
+ "TexCoord3f",
+ "TexCoord3fv",
+ "TexCoord4f",
+ "TexCoord4fv",
+ "Vertex2f",
+ "Vertex2fv",
+ "Vertex3f",
+ "Vertex3fv",
+ "Vertex4f",
+ "Vertex4fv",
+ "VertexAttrib1fNV",
+ "VertexAttrib1fvNV",
+ "VertexAttrib2fNV",
+ "VertexAttrib2fvNV",
+ "VertexAttrib3fNV",
+ "VertexAttrib3fvNV",
+ "VertexAttrib4fNV",
+ "VertexAttrib4fvNV",
+ "VertexAttrib1fARB",
+ "VertexAttrib1fvARB",
+ "VertexAttrib2fARB",
+ "VertexAttrib2fvARB",
+ "VertexAttrib3fARB",
+ "VertexAttrib3fvARB",
+ "VertexAttrib4fARB",
+ "VertexAttrib4fvARB",
+ "EvalMesh1",
+ "EvalMesh2",
+ "Rectf",
+ "DrawArrays",
+ "DrawElements",
+ "DrawRangeElements"
+]
+
+# Extern-like declarations
+keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+for func_name in keys:
+ if "Chromium" == apiutil.Category(func_name):
+ continue
+ if func_name == "BoundsInfoCR":
+ continue
+
+ return_type = apiutil.ReturnType(func_name)
+ params = apiutil.Parameters(func_name)
+
+ if func_name in commoncall_special:
+ print("extern %s vboxDD_gl%s(%s);" % (return_type, func_name,
+ apiutil.MakeDeclarationString( params )))
+ else:
+ if apiutil.MakeDeclarationString(params)=="void":
+ print("extern %s vboxDD_gl%s(GLcontext *ctx);" % (return_type, func_name))
+ else:
+ print("extern %s vboxDD_gl%s(GLcontext *ctx, %s);" % (return_type, func_name,
+ apiutil.MakeDeclarationString( params )))
+
+print("#endif /* __DD_GL_H__ */")
diff --git a/src/VBox/Additions/common/crOpenGL/Darwin_exports.py b/src/VBox/Additions/common/crOpenGL/Darwin_exports.py
new file mode 100644
index 00000000..c3120e4d
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/Darwin_exports.py
@@ -0,0 +1,12 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+import entrypoints
+
+hacks = ["TexImage3D", "TexImage2D", "TexImage1D", "MultiDrawArrays",
+ "BufferData", "BufferSubData", "GetBufferSubData" ]
+
+entrypoints.GenerateEntrypoints(hacks)
+
diff --git a/src/VBox/Additions/common/crOpenGL/FreeBSD_exports.py b/src/VBox/Additions/common/crOpenGL/FreeBSD_exports.py
new file mode 100644
index 00000000..8f63e0a5
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/FreeBSD_exports.py
@@ -0,0 +1,11 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+import entrypoints
+
+hacks = []
+
+entrypoints.GenerateEntrypoints(hacks)
+
diff --git a/src/VBox/Additions/common/crOpenGL/IRIX64_exports.py b/src/VBox/Additions/common/crOpenGL/IRIX64_exports.py
new file mode 100644
index 00000000..674efff1
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/IRIX64_exports.py
@@ -0,0 +1,11 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+import entrypoints
+
+hacks = ["TexImage3D", "EdgeFlagPointer" ]
+
+entrypoints.GenerateEntrypoints(hacks)
+
diff --git a/src/VBox/Additions/common/crOpenGL/LICENSE b/src/VBox/Additions/common/crOpenGL/LICENSE
new file mode 100644
index 00000000..d609a358
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/LICENSE
@@ -0,0 +1,32 @@
+Copyright (c) 2002, Stanford University
+All rights reserved.
+
+Some portions of Chromium are copyrighted by individual organizations.
+Please see the files COPYRIGHT.LLNL and COPYRIGHT.REDHAT for more
+information.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+* Neither the name of Stanford University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/src/VBox/Additions/common/crOpenGL/Linux_exports.py b/src/VBox/Additions/common/crOpenGL/Linux_exports.py
new file mode 100644
index 00000000..79dc8ddd
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/Linux_exports.py
@@ -0,0 +1,10 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+import entrypoints
+
+hacks = []
+
+entrypoints.GenerateEntrypoints(hacks)
diff --git a/src/VBox/Additions/common/crOpenGL/Linux_i386_exports.py b/src/VBox/Additions/common/crOpenGL/Linux_i386_exports.py
new file mode 100755
index 00000000..653b00a2
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/Linux_i386_exports.py
@@ -0,0 +1,96 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+
+def GenerateEntrypoints():
+
+ #apiutil.CopyrightC()
+
+ # Get sorted list of dispatched functions.
+ # The order is very important - it must match cr_opcodes.h
+ # and spu_dispatch_table.h
+ print('%include "iprt/asmdefs.mac"')
+ print("")
+ print("%ifdef RT_ARCH_AMD64")
+ print("extern glim")
+ print("%else ; X86")
+ print("extern glim")
+ print("%endif")
+ print("")
+
+ keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+ for index in range(len(keys)):
+ func_name = keys[index]
+ if apiutil.Category(func_name) == "Chromium":
+ continue
+ if apiutil.Category(func_name) == "VBox":
+ continue
+
+ print("BEGINPROC_EXPORTED gl%s" % func_name)
+ print("%ifdef RT_ARCH_AMD64")
+ print("\tmov \trax, qword glim+%d" % (8*index))
+ print("\tjmp \t[rax]")
+ print("%else ; X86")
+ print("\tmov \teax, dword glim+%d" % (4*index))
+ print("\tjmp \t[eax]")
+ print("%endif")
+ print("ENDPROC gl%s" % func_name)
+ print("")
+
+
+ print(';')
+ print('; Aliases')
+ print(';')
+
+ # Now loop over all the functions and take care of any aliases
+ allkeys = apiutil.GetAllFunctions(sys.argv[1]+"/APIspec.txt")
+ for func_name in allkeys:
+ if "omit" in apiutil.ChromiumProps(func_name):
+ continue
+
+ if func_name in keys:
+ # we already processed this function earlier
+ continue
+
+ # alias is the function we're aliasing
+ alias = apiutil.Alias(func_name)
+ if alias:
+ # this dict lookup should never fail (raise an exception)!
+ index = keys.index(alias)
+ print("BEGINPROC_EXPORTED gl%s" % func_name)
+ print("%ifdef RT_ARCH_AMD64")
+ print("\tmov \trax, qword glim+%d" % (8*index))
+ print("\tjmp \t[rax]")
+ print("%else ; X86")
+ print("\tmov \teax, dword glim+%d" % (4*index))
+ print("\tjmp \t[eax]")
+ print("%endif")
+ print("ENDPROC gl%s" % func_name)
+ print("")
+
+
+ print(';')
+ print('; No-op stubs')
+ print(';')
+
+ # Now generate no-op stub functions
+ for func_name in allkeys:
+ if "stub" in apiutil.ChromiumProps(func_name):
+ print("BEGINPROC_EXPORTED gl%s" % func_name)
+ print("\tleave")
+ print("\tret")
+ print("ENDPROC gl%s" % func_name)
+ print("")
+
+
+GenerateEntrypoints()
+
diff --git a/src/VBox/Additions/common/crOpenGL/Linux_i386_exports_dri.py b/src/VBox/Additions/common/crOpenGL/Linux_i386_exports_dri.py
new file mode 100755
index 00000000..e212fb68
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/Linux_i386_exports_dri.py
@@ -0,0 +1,96 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+
+def GenerateEntrypoints():
+
+ #apiutil.CopyrightC()
+
+ # Get sorted list of dispatched functions.
+ # The order is very important - it must match cr_opcodes.h
+ # and spu_dispatch_table.h
+ print('%include "iprt/asmdefs.mac"')
+ print("")
+ print("%ifdef RT_ARCH_AMD64")
+ print("extern glim")
+ print("%else ; X86")
+ print("extern glim")
+ print("%endif")
+ print("")
+
+ keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+ for index in range(len(keys)):
+ func_name = keys[index]
+ if apiutil.Category(func_name) == "Chromium":
+ continue
+ if apiutil.Category(func_name) == "VBox":
+ continue
+
+ print("BEGINPROC_EXPORTED cr_gl%s" % func_name)
+ print("%ifdef RT_ARCH_AMD64")
+ print("\tmov \trax, qword glim+%d" % (8*index))
+ print("\tjmp \t[rax]")
+ print("%else ; X86")
+ print("\tmov \teax, dword glim+%d" % (4*index))
+ print("\tjmp \t[eax]")
+ print("%endif")
+ print("ENDPROC cr_gl%s" % func_name)
+ print("")
+
+
+ print(';')
+ print('; Aliases')
+ print(';')
+
+ # Now loop over all the functions and take care of any aliases
+ allkeys = apiutil.GetAllFunctions(sys.argv[1]+"/APIspec.txt")
+ for func_name in allkeys:
+ if "omit" in apiutil.ChromiumProps(func_name):
+ continue
+
+ if func_name in keys:
+ # we already processed this function earlier
+ continue
+
+ # alias is the function we're aliasing
+ alias = apiutil.Alias(func_name)
+ if alias:
+ # this dict lookup should never fail (raise an exception)!
+ index = keys.index(alias)
+ print("BEGINPROC_EXPORTED cr_gl%s" % func_name)
+ print("%ifdef RT_ARCH_AMD64")
+ print("\tmov \trax, qword glim+%d" % (8*index))
+ print("\tjmp \t[rax]")
+ print("%else ; X86")
+ print("\tmov \teax, dword glim+%d" % (4*index))
+ print("\tjmp \t[eax]")
+ print("%endif")
+ print("ENDPROC cr_gl%s" % func_name)
+ print("")
+
+
+ print(';')
+ print('; No-op stubs')
+ print(';')
+
+ # Now generate no-op stub functions
+ for func_name in allkeys:
+ if "stub" in apiutil.ChromiumProps(func_name):
+ print("BEGINPROC_EXPORTED cr_gl%s" % func_name)
+ print("\tleave")
+ print("\tret")
+ print("ENDPROC cr_gl%s" % func_name)
+ print("")
+
+
+GenerateEntrypoints()
+
diff --git a/src/VBox/Additions/common/crOpenGL/Linux_i386_glxapi_exports.py b/src/VBox/Additions/common/crOpenGL/Linux_i386_glxapi_exports.py
new file mode 100755
index 00000000..f345e679
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/Linux_i386_glxapi_exports.py
@@ -0,0 +1,109 @@
+from __future__ import print_function
+
+__copyright__ = \
+"""
+Copyright (C) 2009-2019 Oracle Corporation
+
+This file is part of VirtualBox Open Source Edition (OSE), as
+available from http://www.virtualbox.org. This file is free software;
+you can redistribute it and/or modify it under the terms of the GNU
+General Public License (GPL) as published by the Free Software
+Foundation, in version 2 as it comes in the "COPYING" file of the
+VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+"""
+
+import sys
+
+#Note, this should match the fakedri_glxfuncsList.h order
+glx_functions = [
+"CopyContext",
+"UseXFont",
+#"GetDriverConfig",
+"GetProcAddress",
+"QueryExtension",
+"IsDirect",
+"DestroyGLXPbufferSGIX",
+"QueryGLXPbufferSGIX",
+"CreateGLXPixmap",
+"CreateGLXPixmapWithConfigSGIX",
+"QueryContext",
+"CreateContextWithConfigSGIX",
+"SwapBuffers",
+"CreateNewContext",
+"SelectEventSGIX",
+"GetCurrentDrawable",
+"ChooseFBConfig",
+"WaitGL",
+"GetFBConfigs",
+"CreatePixmap",
+"GetSelectedEventSGIX",
+"GetCurrentReadDrawable",
+"GetCurrentDisplay",
+"QueryServerString",
+"CreateWindow",
+"SelectEvent",
+"GetVisualFromFBConfigSGIX",
+"GetFBConfigFromVisualSGIX",
+"QueryDrawable",
+"CreateContext",
+"GetConfig",
+"CreateGLXPbufferSGIX",
+"CreatePbuffer",
+"ChooseFBConfigSGIX",
+"WaitX",
+"GetVisualFromFBConfig",
+#"GetScreenDriver",
+"GetFBConfigAttrib",
+"GetCurrentContext",
+"GetClientString",
+"DestroyPixmap",
+"MakeCurrent",
+"DestroyContext",
+"GetProcAddressARB",
+"GetSelectedEvent",
+"DestroyPbuffer",
+"DestroyWindow",
+"DestroyGLXPixmap",
+"QueryVersion",
+"ChooseVisual",
+"MakeContextCurrent",
+"QueryExtensionsString",
+"GetFBConfigAttribSGIX",
+"FreeMemoryMESA",
+"QueryContextInfoEXT",
+"ImportContextEXT",
+"GetContextIDEXT",
+"MakeCurrentReadSGI",
+"AllocateMemoryMESA",
+"GetMemoryOffsetMESA",
+"CreateGLXPixmapMESA",
+"GetCurrentDisplayEXT",
+"FreeContextEXT"
+];
+
+print('%include "iprt/asmdefs.mac"')
+print("")
+print("%ifdef RT_ARCH_AMD64")
+print("extern glxim")
+print("%else ; X86")
+print("extern glxim")
+print("%endif")
+print("")
+
+## r=bird: This could all be done with macros in the assembler.
+
+for index in range(len(glx_functions)):
+ func_name = glx_functions[index]
+
+ print("BEGINPROC_EXPORTED vbox_glX%s" % func_name)
+ print("%ifdef RT_ARCH_AMD64")
+ print("\tmov \trax, qword glxim+%d" % (8*index))
+ print("\tjmp \t[rax]")
+ print("%else ; X86")
+ print("\tmov \teax, dword glxim+%d" % (4*index))
+ print("\tjmp \t[eax]")
+ print("%endif")
+ print("ENDPROC vbox_glX%s" % func_name)
+ print("")
+
diff --git a/src/VBox/Additions/common/crOpenGL/Makefile.kmk b/src/VBox/Additions/common/crOpenGL/Makefile.kmk
new file mode 100644
index 00000000..4d0011d8
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/Makefile.kmk
@@ -0,0 +1,734 @@
+# $Id: Makefile.kmk $
+## @file
+# Sub-Makefile for the VirtualBox Guest OpenGL part
+#
+
+#
+# Copyright (C) 2008-2019 Oracle Corporation
+#
+# This file is part of VirtualBox Open Source Edition (OSE), as
+# available from http://www.virtualbox.org. This file is free software;
+# you can redistribute it and/or modify it under the terms of the GNU
+# General Public License (GPL) as published by the Free Software
+# Foundation, in version 2 as it comes in the "COPYING" file of the
+# VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+# hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+#
+
+SUB_DEPTH = ../../../../..
+include $(KBUILD_PATH)/subheader.kmk
+
+#
+# Target lists.
+#
+BLDDIRS += \
+ $(VBOX_PATH_CROGL_GENFILES)/
+
+if1of ($(KBUILD_TARGET), win linux solaris freebsd)
+ DLLS += \
+ VBoxOGL \
+ VBoxOGLarrayspu \
+ VBoxOGLpassthroughspu \
+ VBoxOGLpackspu \
+ VBoxOGLfeedbackspu
+endif
+
+VBOX_OGL_X86_GUEST_DLLS = \
+ VBoxOGL-x86 \
+ VBoxOGLarrayspu-x86 \
+ VBoxOGLpassthroughspu-x86 \
+ VBoxOGLpackspu-x86 \
+ VBoxOGLfeedbackspu-x86
+
+ifdef VBOX_WITH_WDDM
+ DLLS.win.amd64 += $(VBOX_OGL_X86_GUEST_DLLS)
+endif
+
+if1of ($(KBUILD_TARGET), linux solaris freebsd)
+ #VBoxOGL_DRI = 1
+ DLLS += VBoxEGL
+ ifn1of ($(KBUILD_TARGET),linux solaris) # No DRI on Solaris yet
+ VBoxOGL_FAKEDRI = 1
+ endif
+
+ # Only Solaris right now needs C stubs because I can't figure out how to
+ # generate the GOT based relocation ASM yet.
+ ifdef VBoxOGL_FAKEDRI
+ if1of ($(KBUILD_TARGET).$(KBUILD_TARGET_ARCH),solaris.x86 solaris.amd64 linux.x86 linux.amd64 freebsd.x86 freebsd.amd64)
+ VBOX_OGL_GLX_USE_CSTUBS = 1
+ endif
+ endif
+endif
+
+
+#
+# VBoxOGL
+#
+VBoxOGL_TEMPLATE = VBOXCROGLR3GUESTDLL
+VBoxOGL_INCS = . $(VBOX_GRAPHICS_INCS)
+if1of ($(KBUILD_TARGET), linux solaris freebsd)
+ ifndef VBOX_USE_SYSTEM_GL_HEADERS
+ VBoxOGL_INCS += \
+ $(VBOX_PATH_X11_ROOT)/libXdamage-1.1 \
+ $(VBOX_PATH_X11_ROOT)/libXcomposite-0.4.0 \
+ $(VBOX_PATH_X11_ROOT)/libXext-1.3.1 \
+ $(VBOX_PATH_X11_ROOT)/libXfixes-4.0.3 \
+ $(VBOX_PATH_X11_ROOT)/damageproto-1.1.0 \
+ $(VBOX_PATH_X11_ROOT)/compositeproto-0.4 \
+ $(VBOX_PATH_X11_ROOT)/fixesproto-4.0 \
+ $(VBOX_PATH_X11_ROOT)/libx11-1.1.5-other \
+ $(VBOX_PATH_X11_ROOT)/xextproto-7.1.1 \
+ $(VBOX_PATH_X11_ROOT)/xproto-7.0.18 \
+ $(VBOX_GL_INCS)
+ endif
+ VBoxOGL_DEFS += VBOX_NO_NATIVEGL
+endif
+
+ifdef VBoxOGL_DRI
+ VBoxOGL_DEFS += VBOXOGL_DRI IN_DRI_DRIVER
+else ifdef VBoxOGL_FAKEDRI
+ VBoxOGL_DEFS += VBOXOGL_FAKEDRI
+ ifdef VBOX_OGL_GLX_USE_CSTUBS
+ VBoxOGL_DEFS += VBOX_OGL_GLX_USE_CSTUBS
+ endif
+endif
+
+ifdef VBOX_WITH_WDDM
+ VBoxOGL_DEFS.win += VBOX_WITH_WDDM
+ VBoxOGL_SDKS.win += $(VBOX_WINDDK_GST_WLH)
+endif
+
+ifeq ($(KBUILD_TARGET),win)
+#fixme?, INTERMEDIATES.win ain't working
+ VBoxOGL_INTERMEDIATES += $(VBOX_PATH_CROGL_GENFILES)/cr_gl.h
+ if defined(VBOX_SIGNING_MODE) && defined(VBOX_WITH_WDDM)
+ VBoxOGL_INSTTYPE.win = none
+ VBoxOGL_DEBUG_INSTTYPE.win = both
+ endif
+endif
+ifdef VBoxOGL_DRI
+ VBoxOGL_INTERMEDIATES += \
+ $(VBOX_PATH_CROGL_GENFILES)/cr_gl.h \
+ $(VBOX_PATH_CROGL_GENFILES)/DD_gl.h
+else ifdef VBoxOGL_FAKEDRI
+ VBoxOGL_INTERMEDIATES += \
+ $(VBOX_PATH_CROGL_GENFILES)/cr_gl.h
+endif
+VBoxOGL_SOURCES += \
+ load.c \
+ stub.c \
+ context.c \
+ $(VBOX_PATH_CROGL_GENFILES)/getprocaddress.c \
+ $(VBOX_PATH_CROGL_GENFILES)/NULLfuncs.c \
+ $(VBOX_PATH_CROGL_GENFILES)/tsfuncs.c
+
+if1of ($(KBUILD_TARGET), linux solaris freebsd)
+ VBoxOGL_SOURCES += \
+ glx.c \
+ xfont.c
+ ifdef VBOX_OGL_GLX_USE_CSTUBS
+ VBoxOGL_SOURCES += glx_c_exports.c
+ endif
+
+ ifdef VBoxOGL_DRI
+ VBoxOGL_SOURCES += \
+ $(VBOX_PATH_CROGL_GENFILES)/DD_gl.c \
+ dri_drv.c
+ VBoxOGL_SOURCES.linux += \
+ $(VBOX_PATH_CROGL_GENFILES)/linux_exports_dri.asm
+ VBoxOGL_SOURCES.solaris += \
+ $(VBOX_PATH_CROGL_GENFILES)/solaris_exports_dri.asm
+ VBoxOGL_SOURCES.freebsd += \
+ $(VBOX_PATH_CROGL_GENFILES)/freebsd_exports_dri.asm
+ else ifdef VBoxOGL_FAKEDRI
+ VBoxOGL_SOURCES += \
+ fakedri_drv.c
+ ifndef VBOX_OGL_GLX_USE_CSTUBS
+ VBoxOGL_SOURCES.solaris += \
+ $(VBOX_PATH_CROGL_GENFILES)/solaris_glxapi_exports.asm \
+ $(VBOX_PATH_CROGL_GENFILES)/solaris_exports_dri.asm
+ VBoxOGL_SOURCES.linux += \
+ $(VBOX_PATH_CROGL_GENFILES)/linux_glxapi_exports.asm \
+ $(VBOX_PATH_CROGL_GENFILES)/linux_exports_dri.asm
+ VBoxOGL_SOURCES.freebsd += \
+ $(VBOX_PATH_CROGL_GENFILES)/freebsd_glxapi_exports.asm \
+ $(VBOX_PATH_CROGL_GENFILES)/freebsd_exports_dri.asm
+ else
+ VBoxOGL_SOURCES.solaris += \
+ $(VBOX_PATH_CROGL_GENFILES)/solaris_exports.c
+ VBoxOGL_SOURCES.linux += \
+ $(VBOX_PATH_CROGL_GENFILES)/linux_exports.c
+ VBoxOGL_SOURCES.freebsd += \
+ $(VBOX_PATH_CROGL_GENFILES)/freebsd_exports.c
+ endif
+ else
+ VBoxOGL_SOURCES.linux += \
+ $(VBOX_PATH_CROGL_GENFILES)/linux_exports.c
+ VBoxOGL_SOURCES.solaris += \
+ $(VBOX_PATH_CROGL_GENFILES)/solaris_exports.c
+ VBoxOGL_SOURCES.freebsd += \
+ $(VBOX_PATH_CROGL_GENFILES)/freebsd_exports.c
+ endif
+endif
+
+VBoxOGL_SOURCES.win = \
+ wgl.c \
+ icd_drv.c \
+ VBoxCROGL.rc \
+ $(VBOX_PATH_CROGL_GENFILES)/windows_exports.asm \
+ $(VBOX_PATH_CROGL_GENFILES)/cropengl.def
+VBoxOGL_CLEAN = \
+ $(VBOX_PATH_CROGL_GENFILES)/getprocaddress.c \
+ $(VBOX_PATH_CROGL_GENFILES)/NULLfuncs.c \
+ $(VBOX_PATH_CROGL_GENFILES)/tsfuncs.c
+VBoxOGL_CLEAN.linux += \
+ $(VBOX_PATH_CROGL_GENFILES)/linux_exports.c
+VBoxOGL_CLEAN.solaris += \
+ $(VBOX_PATH_CROGL_GENFILES)/solaris_exports.c
+VBoxOGL_CLEAN.win = \
+ $(VBOX_PATH_CROGL_GENFILES)/windows_exports.asm \
+ $(VBOX_PATH_CROGL_GENFILES)/cropengl.def
+if1of ($(KBUILD_TARGET), linux solaris)
+ ifdef VBoxOGL_DRI
+ VBoxOGL_CLEAN += \
+ $(VBOX_PATH_CROGL_GENFILES)/cr_gl.h \
+ $(VBOX_PATH_CROGL_GENFILES)/DD_gl.h \
+ $(VBOX_PATH_CROGL_GENFILES)/DD_gl.c
+ else ifdef VBoxOGL_FAKEDRI
+ VBoxOGL_CLEAN += \
+ $(VBOX_PATH_CROGL_GENFILES)/cr_gl.h
+ VBoxOGL_CLEAN.linux += \
+ $(VBOX_PATH_CROGL_GENFILES)/linux_glxapi_exports.asm
+ VBoxOGL_CLEAN.solaris += \
+ $(VBOX_PATH_CROGL_GENFILES)/solaris_glxapi_exports.asm
+ endif
+endif
+# VBoxOGL_LIBS = \ # VBOX_LIB_OGL_CRUTIL includes these and caused an interesting conflict.
+# $(VBOX_LIB_IPRT_GUEST_R3_SHARED) \
+# $(VBOX_LIB_VBGL_R3_SHARED) \
+
+VBoxOGL_LIBS = \
+ $(VBOX_LIB_OGL_CRUTIL) \
+ $(PATH_STAGE_LIB)/additions/VBoxOGLspuload$(VBOX_SUFF_LIB)
+
+VBoxOGL_LIBS.win += \
+ $(PATH_STAGE_LIB)/additions/VBoxDispMpLogger$(VBOX_SUFF_LIB) \
+ $(PATH_STAGE_LIB)/additions/VBoxWddmUmKmt$(VBOX_SUFF_LIB) \
+ $(PATH_STAGE_LIB)/additions/VBoxCrHgsmi$(VBOX_SUFF_LIB)
+
+if1of ($(KBUILD_TARGET), linux solaris freebsd)
+ ifdef VBOX_USE_SYSTEM_GL_HEADERS
+ VBoxOGL_LIBS += Xcomposite Xdamage Xfixes Xext
+ else
+ VBoxOGL_LIBS += \
+ $(PATH_STAGE_LIB)/libXcomposite.so \
+ $(PATH_STAGE_LIB)/libXdamage.so \
+ $(PATH_STAGE_LIB)/libXfixes.so \
+ $(PATH_STAGE_LIB)/libXext.so
+ endif
+ ifdef VBoxOGL_FAKEDRI
+ ifeq ($(KBUILD_TARGET), freebsd)
+ VBoxOGL_LIBS += \
+ elf
+ else
+ VBoxOGL_LIBS += \
+ dl
+ endif
+ else
+ VBoxOGL_SONAME.linux = libGL.so.1
+ VBoxOGL_LDFLAGS.linux += -Wl,-e,LibMain
+ endif
+endif
+ifdef VBOX_WITH_CRHGSMI
+VBoxOGL_DEFS.win += VBOX_WITH_CRHGSMI
+endif
+ifdef VBOX_WITH_WDDM
+VBoxOGL_DEFS.win += VBOX_WITH_WDDM
+endif
+if1of ($(KBUILD_TARGET), linux)
+VBoxOGL_LDFLAGS += -Wl,-z,nodelete
+endif
+ifdef VBOX_WITH_WDDM
+#
+# VBoxOGL-x86 - x86 VBoxOGL version built for amd64 build
+#
+VBoxOGL-x86_EXTENDS = VBoxOGL
+VBoxOGL-x86_BLD_TRG_ARCH = x86
+VBoxOGL-x86_LIBS = $(VBOX_LIB_IPRT_GUEST_R3_SHARED_X86) \
+ $(VBOX_LIB_VBGL_R3_SHARED_X86) \
+ $(VBOX_LIB_OGL_CRUTIL_X86) \
+ $(PATH_STAGE_LIB)/additions/VBoxOGLspuload-x86$(VBOX_SUFF_LIB)
+
+VBoxOGL-x86_LIBS.win += \
+ $(PATH_STAGE_LIB)/additions/VBoxDispMpLogger-x86$(VBOX_SUFF_LIB) \
+ $(PATH_STAGE_LIB)/additions/VBoxWddmUmKmt-x86$(VBOX_SUFF_LIB) \
+ $(PATH_STAGE_LIB)/additions/VBoxCrHgsmi-x86$(VBOX_SUFF_LIB)
+
+
+VBoxOGL-x86_SOURCES.win = $(subst cropengl.def,cropengl-x86.def,$(VBoxOGL_SOURCES.win))
+VBoxOGL-x86_CLEAN.win = $(subst cropengl.def,cropengl-x86.def,$(VBoxOGL_CLEAN.win))
+VBoxOGL-x86_DEFS = $(VBoxOGL_DEFS) VBOX_WDDM_WOW64
+endif
+
+#
+# Generate files for VBoxOGL.
+#
+$(VBOX_PATH_CROGL_GENFILES)/NULLfuncs.c: $(PATH_SUB_CURRENT)/NULLfuncs.py $(VBOX_CROGL_API_FILES) | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI)
+
+$(VBOX_PATH_CROGL_GENFILES)/tsfuncs.c: $(PATH_SUB_CURRENT)/tsfuncs.py $(VBOX_CROGL_API_FILES) | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI)
+
+
+ifeq ($(KBUILD_TARGET),win)
+ # Windows
+$(VBOX_PATH_CROGL_GENFILES)/getprocaddress.c: $(PATH_SUB_CURRENT)/windows_getprocaddress.py $(VBOX_CROGL_API_FILES) | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI)
+
+ ifeq ($(KBUILD_TARGET_ARCH),amd64)
+$(VBOX_PATH_CROGL_GENFILES)/cropengl.def: $(PATH_SUB_CURRENT)/defs64.py $(VBOX_CROGL_API_FILES) | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI)
+ else
+$(VBOX_PATH_CROGL_GENFILES)/cropengl.def: $(PATH_SUB_CURRENT)/defs.py $(VBOX_CROGL_API_FILES) | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI)
+ endif
+
+$(VBOX_PATH_CROGL_GENFILES)/cr_gl.h: $(PATH_SUB_CURRENT)/cr_gl.py $(VBOX_CROGL_API_FILES) | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI)
+
+$(VBOX_PATH_CROGL_GENFILES)/windows_exports.asm: \
+ $(PATH_SUB_CURRENT)/windows_i386_exports.py \
+ $(VBOX_CROGL_API_FILES) $(PATH_SUB_CURRENT)/entrypoints.py \
+ | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI)
+
+ ifdef VBOX_WITH_WDDM
+ ifeq ($(KBUILD_TARGET).$(KBUILD_TARGET_ARCH),win.amd64)
+$(VBOX_PATH_CROGL_GENFILES)/cropengl-x86.def: $(PATH_SUB_CURRENT)/defs.py $(VBOX_CROGL_API_FILES) | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI)
+ endif #ifeq ($(KBUILD_TARGET).$(KBUILD_TARGET_ARCH),win.amd64)
+ endif #ifdef VBOX_WITH_WDDM
+
+
+else if1of ($(KBUILD_TARGET), freebsd linux solaris)
+ # FreeBSD, Linux, Solaris
+$(VBOX_PATH_CROGL_GENFILES)/getprocaddress.c: $(PATH_SUB_CURRENT)/getprocaddress.py $(VBOX_CROGL_API_FILES) | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI)
+
+ if !defined(VBoxOGL_DRI) && !defined(VBoxOGL_FAKEDRI)
+ ifeq ($(KBUILD_TARGET),solaris)
+$(VBOX_PATH_CROGL_GENFILES)/solaris_exports.c: \
+ $(PATH_SUB_CURRENT)/SunOS_exports.py \
+ $(VBOX_CROGL_API_FILES) $(PATH_SUB_CURRENT)/entrypoints.py \
+ | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI)
+
+ else ifeq ($(KBUILD_TARGET),freebsd)
+$(VBOX_PATH_CROGL_GENFILES)/freebsd_exports.c: \
+ $(PATH_SUB_CURRENT)/FreeBSD_exports.py \
+ $(VBOX_CROGL_API_FILES) $(PATH_SUB_CURRENT)/entrypoints.py \
+ | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI)
+
+ else
+$(VBOX_PATH_CROGL_GENFILES)/linux_exports.c: \
+ $(PATH_SUB_CURRENT)/Linux_exports.py \
+ $(VBOX_CROGL_API_FILES) $(PATH_SUB_CURRENT)/entrypoints.py \
+ | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI)
+ endif
+
+ else ifdef VBoxOGL_DRI
+$(VBOX_PATH_CROGL_GENFILES)/cr_gl.h: $(PATH_SUB_CURRENT)/cr_gl.py $(VBOX_CROGL_API_FILES) | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI)
+
+$(VBOX_PATH_CROGL_GENFILES)/DD_gl.h: $(PATH_SUB_CURRENT)/DD_glh.py $(VBOX_CROGL_API_FILES) | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI)
+
+$(VBOX_PATH_CROGL_GENFILES)/DD_gl.c: $(PATH_SUB_CURRENT)/DD_glc.py $(VBOX_CROGL_API_FILES) | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI)
+
+ ifeq ($(KBUILD_TARGET),solaris)
+$(VBOX_PATH_CROGL_GENFILES)/solaris_exports_dri.asm: \
+ $(PATH_SUB_CURRENT)/SunOS_i386_exports_dri.py \
+ $(VBOX_CROGL_API_FILES) $(PATH_SUB_CURRENT)/entrypoints.py \
+ | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI)
+
+ else ifeq ($(KBUILD_TARGET),freebsd)
+$(VBOX_PATH_CROGL_GENFILES)/freebsd_exports_dri.asm: \
+ $(PATH_SUB_CURRENT)/FreeBSD_i386_exports_dri.py \
+ $(VBOX_CROGL_API_FILES) $(PATH_SUB_CURRENT)/entrypoints.py \
+ | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI)
+
+ else
+$(VBOX_PATH_CROGL_GENFILES)/linux_exports_dri.asm: \
+ $(PATH_SUB_CURRENT)/Linux_i386_exports_dri.py \
+ $(VBOX_CROGL_API_FILES) $(PATH_SUB_CURRENT)/entrypoints.py \
+ | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI)
+ endif
+
+ else ifdef VBoxOGL_FAKEDRI
+$(VBOX_PATH_CROGL_GENFILES)/cr_gl.h: $(PATH_SUB_CURRENT)/cr_gl.py $(VBOX_CROGL_API_FILES) | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI)
+
+ ifndef VBOX_OGL_GLX_USE_CSTUBS
+ ifeq ($(KBUILD_TARGET),solaris)
+$(VBOX_PATH_CROGL_GENFILES)/solaris_exports_dri.asm: \
+ $(PATH_SUB_CURRENT)/SunOS_i386_exports_dri.py \
+ $(VBOX_CROGL_API_FILES) $(PATH_SUB_CURRENT)/entrypoints.py \
+ | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI)
+$(VBOX_PATH_CROGL_GENFILES)/solaris_glxapi_exports.asm: $(PATH_SUB_CURRENT)/SunOS_i386_glxapi_exports.py | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $<
+
+ else
+$(VBOX_PATH_CROGL_GENFILES)/linux_exports_dri.asm: \
+ $(PATH_SUB_CURRENT)/Linux_i386_exports_dri.py \
+ $(VBOX_CROGL_API_FILES) $(PATH_SUB_CURRENT)/entrypoints.py \
+ | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI)
+$(VBOX_PATH_CROGL_GENFILES)/linux_glxapi_exports.asm: $(PATH_SUB_CURRENT)/Linux_i386_glxapi_exports.py | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $<
+ endif
+
+ else
+ ifeq ($(KBUILD_TARGET),solaris)
+$(VBOX_PATH_CROGL_GENFILES)/solaris_exports.c: \
+ $(PATH_SUB_CURRENT)/SunOS_exports.py \
+ $(VBOX_CROGL_API_FILES) $(PATH_SUB_CURRENT)/entrypoints.py \
+ | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI)
+
+ else ifeq ($(KBUILD_TARGET),freebsd)
+$(VBOX_PATH_CROGL_GENFILES)/freebsd_exports.c: \
+ $(PATH_SUB_CURRENT)/FreeBSD_exports.py \
+ $(VBOX_CROGL_API_FILES) $(PATH_SUB_CURRENT)/entrypoints.py \
+ | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI)
+ else
+$(VBOX_PATH_CROGL_GENFILES)/linux_exports.c: \
+ $(PATH_SUB_CURRENT)/Linux_exports.py \
+ $(VBOX_CROGL_API_FILES) $(PATH_SUB_CURRENT)/entrypoints.py \
+ | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI)
+ endif
+
+ endif # VBOX_OGL_GLX_USE_CSTUBS
+ endif
+endif
+
+#
+# VBoxOGLarrayspu
+#
+VBoxOGLarrayspu_TEMPLATE = VBOXCROGLR3GUESTDLL
+VBoxOGLarrayspu_INCS = \
+ array \
+ $(VBOX_GRAPHICS_INCS)
+if1of ($(KBUILD_TARGET), linux solaris freebsd)
+ VBoxOGLarrayspu_INCS += \
+ $(VBOX_GL_INCS)
+endif
+if defined(VBOX_SIGNING_MODE) && defined(VBOX_WITH_WDDM)
+ VBoxOGLarrayspu_INSTTYPE.win = none
+ VBoxOGLarrayspu_DEBUG_INSTTYPE.win = both
+endif
+VBoxOGLarrayspu_INCS.darwin += $(PATH_OUT)/obj/VBoxOGL
+VBoxOGLarrayspu_INTERMEDIATES = \
+ $(VBOX_PATH_CROGL_GENFILES)/state/cr_currentpointers.h \
+ $(VBOX_PATH_CROGL_GENFILES)/state/cr_statefuncs.h
+VBoxOGLarrayspu_SOURCES = \
+ array/arrayspu.c \
+ array/arrayspu_config.c \
+ array/arrayspu_init.c
+VBoxOGLarrayspu_SOURCES.win = \
+ array/arrayspu.def \
+ array/arrayspu.rc
+VBoxOGLarrayspu_LIBS = \
+ $(VBOX_LIB_OGL_CRUTIL) \
+ $(PATH_STAGE_LIB)/additions/VBoxOGLspuload$(VBOX_SUFF_LIB) \
+ $(PATH_STAGE_LIB)/additions/VBoxOGLcrstate$(VBOX_SUFF_LIB)
+ifdef VBOX_WITH_CRHGSMI
+VBoxOGLarrayspu_DEFS.win += VBOX_WITH_CRHGSMI
+endif
+ifdef VBOX_WITH_WDDM
+VBoxOGLarrayspu_DEFS.win += VBOX_WITH_WDDM
+endif
+
+ifdef VBOX_WITH_WDDM
+#
+# VBoxOGLarrayspu-x86 - x86 version of VBoxOGLarrayspu built for amd64 build
+#
+VBoxOGLarrayspu-x86_EXTENDS = VBoxOGLarrayspu
+VBoxOGLarrayspu-x86_BLD_TRG_ARCH = x86
+VBoxOGLarrayspu-x86_LIBS = $(VBOX_LIB_OGL_CRUTIL_X86) \
+ $(PATH_STAGE_LIB)/additions/VBoxOGLspuload-x86$(VBOX_SUFF_LIB) \
+ $(PATH_STAGE_LIB)/additions/VBoxOGLcrstate-x86$(VBOX_SUFF_LIB)
+VBoxOGLarrayspu-x86_DEFS = $(VBoxOGLarrayspu_DEFS) VBOX_WDDM_WOW64
+endif
+
+#
+# VBoxOGLpassthroughspu
+#
+VBoxOGLpassthroughspu_TEMPLATE = VBOXCROGLR3GUESTDLL
+VBoxOGLpassthroughspu_INCS = \
+ passthrough \
+ $(VBOX_GRAPHICS_INCS)
+if1of ($(KBUILD_TARGET), linux solaris freebsd)
+ VBoxOGLpassthroughspu_INCS += \
+ $(VBOX_GL_INCS)
+endif
+if defined(VBOX_SIGNING_MODE) && defined(VBOX_WITH_WDDM)
+ VBoxOGLpassthroughspu_INSTTYPE.win = none
+ VBoxOGLpassthroughspu_DEBUG_INSTTYPE.win = both
+endif
+VBoxOGLpassthroughspu_SOURCES = \
+ passthrough/passthroughspu_init.c \
+ $(VBOX_PATH_CROGL_GENFILES)/passthroughspu.c
+VBoxOGLpassthroughspu_SOURCES.win = \
+ passthrough/passthrough.def \
+ passthrough/passthroughspu.rc
+VBoxOGLpassthroughspu_CLEAN = \
+ $(VBOX_PATH_CROGL_GENFILES)/passthroughspu.c
+VBoxOGLpassthroughspu_LIBS = \
+ $(VBOX_LIB_OGL_CRUTIL)
+ifdef VBOX_WITH_CRHGSMI
+VBoxOGLpassthroughspu_DEFS.win += VBOX_WITH_CRHGSMI
+endif
+ifdef VBOX_WITH_WDDM
+VBoxOGLpassthroughspu_DEFS.win += VBOX_WITH_WDDM
+endif
+
+ifdef VBOX_WITH_WDDM
+#
+# VBoxOGLpassthroughspu-x86 - x86 version of VBoxOGLpassthroughspu built for amd64 build
+#
+VBoxOGLpassthroughspu-x86_EXTENDS = VBoxOGLpassthroughspu
+VBoxOGLpassthroughspu-x86_BLD_TRG_ARCH = x86
+VBoxOGLpassthroughspu-x86_LIBS = $(VBOX_LIB_OGL_CRUTIL_X86)
+VBoxOGLpassthroughspu-x86_DEFS = $(VBoxOGLpassthroughspu_DEFS) VBOX_WDDM_WOW64
+endif
+
+#
+# Generate files for VBoxOGLpassthroughspu.
+#
+$(VBOX_PATH_CROGL_GENFILES)/passthroughspu.c: $(PATH_SUB_CURRENT)/passthrough/passthrough.py $(VBOX_CROGL_API_FILES) | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI)
+
+#
+# VBoxOGLpackspu
+#
+VBoxOGLpackspu_TEMPLATE = VBOXCROGLR3GUESTDLL
+VBoxOGLpackspu_DEFS = TRACKS_STATE=1 PACKS=1
+VBoxOGLpackspu_INCS = \
+ pack \
+ $(VBOX_GRAPHICS_INCS)
+if1of ($(KBUILD_TARGET), linux solaris freebsd)
+ VBoxOGLpackspu_INCS += \
+ $(VBOX_GL_INCS)
+endif
+if defined(VBOX_SIGNING_MODE) && defined(VBOX_WITH_WDDM)
+ VBoxOGLpackspu_INSTTYPE.win = none
+ VBoxOGLpackspu_DEBUG_INSTTYPE.win = both
+endif
+VBoxOGLpackspu_INTERMEDIATES = \
+ $(VBOX_PATH_CROGL_GENFILES)/packspu_proto.h \
+ $(VBOX_PATH_CROGL_GENFILES)/cr_packfunctions.h
+VBoxOGLpackspu_SOURCES = \
+ pack/packspu_bufferobject.c \
+ pack/packspu_client.c \
+ pack/packspu_config.c \
+ pack/packspu_context.c \
+ pack/packspu_getstring.c \
+ pack/packspu_init.c \
+ pack/packspu_misc.c \
+ pack/packspu_net.c \
+ pack/packspu_swapbuf.c \
+ pack/packspu_pixel.c \
+ pack/packspu_texture.c \
+ pack/packspu_getshaders.c \
+ pack/packspu_glsl.c \
+ pack/packspu_framebuffer.c \
+ $(VBOX_PATH_CROGL_GENFILES)/packspu.c \
+ $(VBOX_PATH_CROGL_GENFILES)/packspu_get.c \
+ $(VBOX_PATH_CROGL_GENFILES)/packspu_flush.c \
+ $(VBOX_PATH_CROGL_GENFILES)/packspu_beginend.c
+VBoxOGLpackspu_SOURCES.win = \
+ pack/pack.def \
+ pack/packspu.rc
+VBoxOGLpackspu_CLEAN = \
+ $(VBOX_PATH_CROGL_GENFILES)/packspu_proto.h \
+ $(VBOX_PATH_CROGL_GENFILES)/packspu.c \
+ $(VBOX_PATH_CROGL_GENFILES)/packspu_get.c \
+ $(VBOX_PATH_CROGL_GENFILES)/packspu_flush.c \
+ $(VBOX_PATH_CROGL_GENFILES)/packspu_beginend.c
+VBoxOGLpackspu_LIBS = \
+ $(VBOX_LIB_OGL_CRUTIL) \
+ $(PATH_STAGE_LIB)/additions/VBoxOGLspuload$(VBOX_SUFF_LIB) \
+ $(PATH_STAGE_LIB)/additions/VBoxOGLcrstate$(VBOX_SUFF_LIB) \
+ $(PATH_STAGE_LIB)/additions/VBoxOGLcrpacker$(VBOX_SUFF_LIB)
+VBoxOGLpackspu_LIBS.win += \
+ $(PATH_STAGE_LIB)/additions/VBoxDispMpLogger$(VBOX_SUFF_LIB) \
+ $(PATH_STAGE_LIB)/additions/VBoxWddmUmKmt$(VBOX_SUFF_LIB) \
+ $(PATH_STAGE_LIB)/additions/VBoxCrHgsmi$(VBOX_SUFF_LIB)
+
+ifdef VBOX_WITH_CRHGSMI
+VBoxOGLpackspu_DEFS.win += VBOX_WITH_CRHGSMI
+endif
+ifdef VBOX_WITH_CRDUMPER
+VBoxOGLpackspu_DEFS += VBOX_WITH_CRDUMPER
+endif
+ifdef VBOX_WITH_CRPACKSPU_DUMPER
+VBoxOGLpackspu_DEFS += VBOX_WITH_CRPACKSPU_DUMPER
+endif
+ifdef VBOX_WITH_WDDM
+VBoxOGLpackspu_DEFS.win += VBOX_WITH_WDDM
+endif
+
+ifdef VBOX_WITH_WDDM
+#
+# VBoxOGLpackspu-x86 - x86 version of VBoxOGLpackspu built for amd64 build
+#
+VBoxOGLpackspu-x86_EXTENDS = VBoxOGLpackspu
+VBoxOGLpackspu-x86_BLD_TRG_ARCH = x86
+VBoxOGLpackspu-x86_LIBS = $(VBOX_LIB_OGL_CRUTIL_X86) \
+ $(PATH_STAGE_LIB)/additions/VBoxOGLspuload-x86$(VBOX_SUFF_LIB) \
+ $(PATH_STAGE_LIB)/additions/VBoxOGLcrstate-x86$(VBOX_SUFF_LIB) \
+ $(PATH_STAGE_LIB)/additions/VBoxOGLcrpacker-x86$(VBOX_SUFF_LIB)
+VBoxOGLpackspu-x86_LIBS.win += \
+ $(PATH_STAGE_LIB)/additions/VBoxDispMpLogger-x86$(VBOX_SUFF_LIB) \
+ $(PATH_STAGE_LIB)/additions/VBoxWddmUmKmt-x86$(VBOX_SUFF_LIB) \
+ $(PATH_STAGE_LIB)/additions/VBoxCrHgsmi-x86$(VBOX_SUFF_LIB)
+VBoxOGLpackspu-x86_DEFS = $(VBoxOGLpackspu_DEFS) VBOX_WDDM_WOW64
+endif
+
+#
+# Generate files for VBoxOGLpackspu.
+#
+$(VBOX_PATH_CROGL_GENFILES)/packspu.c: $(addprefix $(PATH_SUB_CURRENT)/pack/,pack.py packspu_special packspu_unimplemented_special) $(VBOX_CROGL_API_FILES) | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI) $(<D)
+
+$(VBOX_PATH_CROGL_GENFILES)/packspu_get.c: $(PATH_SUB_CURRENT)/pack/packspu_get.py $(PATH_SUB_CURRENT)/pack/packspu_special $(PATH_ROOT)/src/VBox/HostServices/SharedOpenGL/crserverlib/get_sizes.py $(VBOX_CROGL_API_FILES) | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI) $(<D)
+
+$(VBOX_PATH_CROGL_GENFILES)/packspu_flush.c: $(PATH_SUB_CURRENT)/pack/packspu_flush.py $(PATH_SUB_CURRENT)/pack/packspu_flush_special $(VBOX_CROGL_API_FILES) | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI) $(<D)
+
+$(VBOX_PATH_CROGL_GENFILES)/packspu_beginend.c: $(PATH_SUB_CURRENT)/pack/packspu_beginend.py $(PATH_SUB_CURRENT)/pack/packspu_vertex_special $(VBOX_CROGL_API_FILES) | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI) $(<D)
+
+$(VBOX_PATH_CROGL_GENFILES)/packspu_proto.h: $(addprefix $(PATH_SUB_CURRENT)/pack/,packspu_proto.py packspu_special packspu_unimplemented_special) $(VBOX_CROGL_API_FILES) | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI) $(<D)
+
+#
+# VBoxOGLfeedbackspu
+#
+VBoxOGLfeedbackspu_TEMPLATE = VBOXCROGLR3GUESTDLL
+VBoxOGLfeedbackspu_INCS = \
+ feedback \
+ $(VBOX_GRAPHICS_INCS)
+if1of ($(KBUILD_TARGET), linux solaris freebsd)
+ VBoxOGLfeedbackspu_INCS += \
+ $(VBOX_GL_INCS)
+endif
+if defined(VBOX_SIGNING_MODE) && defined(VBOX_WITH_WDDM)
+ VBoxOGLfeedbackspu_INSTTYPE.win = none
+ VBoxOGLfeedbackspu_DEBUG_INSTTYPE.win = both
+endif
+VBoxOGLarrayspu_INTERMEDIATES = \
+ $(VBOX_PATH_CROGL_GENFILES)/feedbackspu_proto.h
+VBoxOGLfeedbackspu_SOURCES = \
+ feedback/feedbackspu_config.c \
+ feedback/feedbackspu_init.c \
+ feedback/feedback_context.c \
+ $(VBOX_PATH_CROGL_GENFILES)/feedbackspu.c \
+ $(VBOX_PATH_CROGL_GENFILES)/feedbackspu_state.c
+VBoxOGLfeedbackspu_SOURCES.win = \
+ feedback/feedback.def \
+ feedback/feedbackspu.rc
+VBoxOGLfeedbackspu_CLEAN = \
+ $(VBOX_PATH_CROGL_GENFILES)/feedbackspu_proto.h \
+ $(VBOX_PATH_CROGL_GENFILES)/feedbackspu.c \
+ $(VBOX_PATH_CROGL_GENFILES)/feedbackspu_state.c
+VBoxOGLfeedbackspu_LIBS = \
+ $(VBOX_LIB_OGL_CRUTIL) \
+ $(PATH_STAGE_LIB)/additions/VBoxOGLspuload$(VBOX_SUFF_LIB) \
+ $(PATH_STAGE_LIB)/additions/VBoxOGLcrstate$(VBOX_SUFF_LIB)
+ifdef VBOX_WITH_CRHGSMI
+VBoxOGLfeedbackspu_DEFS.win += VBOX_WITH_CRHGSMI
+endif
+ifdef VBOX_WITH_WDDM
+VBoxOGLfeedbackspu_DEFS.win += VBOX_WITH_WDDM
+endif
+
+ifdef VBOX_WITH_WDDM
+#
+# VBoxOGLfeedbackspu-x86 - x86 version of VBoxOGLfeedbackspu built for amd64 build
+#
+VBoxOGLfeedbackspu-x86_EXTENDS = VBoxOGLfeedbackspu
+VBoxOGLfeedbackspu-x86_BLD_TRG_ARCH = x86
+VBoxOGLfeedbackspu-x86_LIBS = $(VBOX_LIB_OGL_CRUTIL_X86) \
+ $(PATH_STAGE_LIB)/additions/VBoxOGLspuload-x86$(VBOX_SUFF_LIB) \
+ $(PATH_STAGE_LIB)/additions/VBoxOGLcrstate-x86$(VBOX_SUFF_LIB)
+VBoxOGLfeedbackspu-x86_DEFS = $(VBoxOGLfeedbackspu_DEFS) VBOX_WDDM_WOW64
+endif
+
+#
+# Generate files for VBoxOGLfeedbackspu.
+#
+$(VBOX_PATH_CROGL_GENFILES)/feedbackspu.c: $(addprefix $(PATH_SUB_CURRENT)/feedback/,feedback.py feedback_special select_special feedback_state_special) $(VBOX_CROGL_API_FILES) | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI) $(<D)
+
+$(VBOX_PATH_CROGL_GENFILES)/feedbackspu_state.c: $(addprefix $(PATH_SUB_CURRENT)/feedback/,feedback_state.py feedback_state_special) $(VBOX_CROGL_API_FILES) | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI) $(<D)
+
+$(VBOX_PATH_CROGL_GENFILES)/feedbackspu_proto.h: $(addprefix $(PATH_SUB_CURRENT)/feedback/,feedbackspu_proto.py feedback_special select_special feedback_state_special) $(VBOX_CROGL_API_FILES) | $$(dir $$@)
+ $(call MSG_GENERATE,python,$@,$<)
+ $(QUIET)$(call VBOX_CROGL_PYTHON_ENV,$(VBOX_PATH_CROGL_PYTHON_INCLUDE),$@) $(VBOX_BLD_PYTHON) $< $(VBOX_PATH_CROGL_GLAPI) $(<D)
+
+VBoxEGL_TEMPLATE = VBOXCROGLR3GUESTDLL
+VBoxEGL_SOURCES = egl.c
+ifndef VBOX_USE_SYSTEM_GL_HEADERS
+ VBoxEGL_INCS = $(VBOX_PATH_X11_ROOT)/mesa-11.0.7
+endif
+VBoxEGL_LIBS = $(VBOX_LIB_OGL) # $(VBOX_LIB_IPRT_GUEST_R3_SHARED)
+VBoxEGL_SONAME.linux = libEGL.so.1
+
+include $(FILE_KBUILD_SUB_FOOTER)
+
diff --git a/src/VBox/Additions/common/crOpenGL/NULLfuncs.py b/src/VBox/Additions/common/crOpenGL/NULLfuncs.py
new file mode 100755
index 00000000..a6427837
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/NULLfuncs.py
@@ -0,0 +1,58 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+apiutil.CopyrightC()
+
+print("""
+/* DO NOT EDIT - THIS FILE GENERATED BY THE NULLfuncs.py SCRIPT */
+
+#include "cr_error.h"
+#include "stub.h"
+""")
+
+for func_name in keys:
+ return_type = apiutil.ReturnType(func_name)
+ params = apiutil.Parameters(func_name)
+
+ print("static %s SPULOAD_APIENTRY NULL_%s(%s)" % (return_type, func_name, apiutil.MakeDeclarationString(params)))
+ print("{")
+ print("\t/* do nothing */")
+ print("\tcrWarning(\"YOU ARE CALLING A NULLED FUNCTION (%s)\");" % func_name)
+ for (name, type, vecSize) in params:
+ print("\t(void) %s;" % name)
+ if return_type != "void":
+ print("\treturn 0;")
+ print("}")
+ print("")
+
+
+print("DECLEXPORT(SPUDispatchTable) stubNULLDispatch = {")
+for func_name in keys:
+ print("\tNULL_%s," % (func_name))
+print("\tNULL, /* copyList */")
+print("\tNULL, /* copy_of */")
+print("\t0, /* mark */")
+print("\tNULL /* server */")
+print("};")
+
+print("")
+print("/* Declare and initialize the glim dispatch table here so that we */")
+print("/* can initialize all entries to no-op routines. */")
+print("SPUDispatchTable glim = {")
+for func_name in keys:
+ print("\tNULL_%s," % (func_name))
+print("\tNULL, /* copyList */")
+print("\tNULL, /* copy_of */")
+print("\t0, /* mark */")
+print("\tNULL /* server */")
+print("};")
diff --git a/src/VBox/Additions/common/crOpenGL/OSF1_exports.py b/src/VBox/Additions/common/crOpenGL/OSF1_exports.py
new file mode 100644
index 00000000..8f63e0a5
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/OSF1_exports.py
@@ -0,0 +1,11 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+import entrypoints
+
+hacks = []
+
+entrypoints.GenerateEntrypoints(hacks)
+
diff --git a/src/VBox/Additions/common/crOpenGL/SunOS_exports.py b/src/VBox/Additions/common/crOpenGL/SunOS_exports.py
new file mode 100644
index 00000000..8f63e0a5
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/SunOS_exports.py
@@ -0,0 +1,11 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+import entrypoints
+
+hacks = []
+
+entrypoints.GenerateEntrypoints(hacks)
+
diff --git a/src/VBox/Additions/common/crOpenGL/SunOS_i386_exports.py b/src/VBox/Additions/common/crOpenGL/SunOS_i386_exports.py
new file mode 100755
index 00000000..b3591339
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/SunOS_i386_exports.py
@@ -0,0 +1,98 @@
+"""
+Copyright (C) 2009-2019 Oracle Corporation
+
+This file is part of VirtualBox Open Source Edition (OSE), as
+available from http://www.virtualbox.org. This file is free software;
+you can redistribute it and/or modify it under the terms of the GNU
+General Public License (GPL) as published by the Free Software
+Foundation, in version 2 as it comes in the "COPYING" file of the
+VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+"""
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+
+def GenerateEntrypoints():
+
+ #apiutil.CopyrightC()
+
+ # Get sorted list of dispatched functions.
+ # The order is very important - it must match cr_opcodes.h
+ # and spu_dispatch_table.h
+ print('%include "iprt/asmdefs.mac"')
+ print("")
+ print("%ifdef RT_ARCH_AMD64")
+ print("extern glim")
+ print("%else ; X86")
+ print("extern glim")
+ print("%endif")
+ print("")
+
+ keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+ for index in range(len(keys)):
+ func_name = keys[index]
+ if apiutil.Category(func_name) == "Chromium":
+ continue
+ if apiutil.Category(func_name) == "VBox":
+ continue
+
+ print("BEGINPROC_EXPORTED gl%s" % func_name)
+ print("%ifdef RT_ARCH_AMD64")
+ print("\tjmp \t[glim+%d wrt rip wrt ..gotpcrel]" % (8*index))
+ print("%else ; X86")
+ print("\tjmp \t[glim+%d wrt ..gotpc]" % (4*index))
+ print("%endif")
+ print("ENDPROC gl%s" % func_name)
+ print("")
+
+
+ print(';')
+ print('; Aliases')
+ print(';')
+
+ # Now loop over all the functions and take care of any aliases
+ allkeys = apiutil.GetAllFunctions(sys.argv[1]+"/APIspec.txt")
+ for func_name in allkeys:
+ if "omit" in apiutil.ChromiumProps(func_name):
+ continue
+
+ if func_name in keys:
+ # we already processed this function earlier
+ continue
+
+ # alias is the function we're aliasing
+ alias = apiutil.Alias(func_name)
+ if alias:
+ # this dict lookup should never fail (raise an exception)!
+ index = keys.index(alias)
+ print("BEGINPROC_EXPORTED gl%s" % func_name)
+ print("%ifdef RT_ARCH_AMD64")
+ print("\tjmp \t[glim+%d wrt rip wrt ..gotpcrel]" % (8*index))
+ print("%else ; X86")
+ print("\tjmp \t[glim+%d wrt ..gotpc]" % (4*index))
+ print("%endif")
+ print("ENDPROC gl%s" % func_name)
+ print("")
+
+
+ print(';')
+ print('; No-op stubs')
+ print(';')
+
+ # Now generate no-op stub functions
+ for func_name in allkeys:
+ if "stub" in apiutil.ChromiumProps(func_name):
+ print("BEGINPROC_EXPORTED gl%s" % func_name)
+ print("\tleave")
+ print("\tret")
+ print("ENDPROC gl%s" % func_name)
+ print("")
+
+
+GenerateEntrypoints()
+
diff --git a/src/VBox/Additions/common/crOpenGL/SunOS_i386_exports_dri.py b/src/VBox/Additions/common/crOpenGL/SunOS_i386_exports_dri.py
new file mode 100755
index 00000000..a8b951bd
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/SunOS_i386_exports_dri.py
@@ -0,0 +1,98 @@
+"""
+Copyright (C) 2009-2019 Oracle Corporation
+
+This file is part of VirtualBox Open Source Edition (OSE), as
+available from http://www.virtualbox.org. This file is free software;
+you can redistribute it and/or modify it under the terms of the GNU
+General Public License (GPL) as published by the Free Software
+Foundation, in version 2 as it comes in the "COPYING" file of the
+VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+"""
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+
+def GenerateEntrypoints():
+
+ #apiutil.CopyrightC()
+
+ # Get sorted list of dispatched functions.
+ # The order is very important - it must match cr_opcodes.h
+ # and spu_dispatch_table.h
+ print('%include "iprt/asmdefs.mac"')
+ print("")
+ print("%ifdef RT_ARCH_AMD64")
+ print("extern glim")
+ print("%else ; X86")
+ print("extern glim")
+ print("%endif")
+ print("")
+
+ keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+ for index in range(len(keys)):
+ func_name = keys[index]
+ if apiutil.Category(func_name) == "Chromium":
+ continue
+ if apiutil.Category(func_name) == "VBox":
+ continue
+
+ print("BEGINPROC_EXPORTED cr_gl%s" % func_name)
+ print("%ifdef RT_ARCH_AMD64")
+ print("\tjmp \t[glim+%d wrt rip wrt ..gotpcrel]" % (8*index))
+ print("%else ; X86")
+ print("\tjmp \t[glim+%d wrt ..gotpc]" % (4*index))
+ print("%endif")
+ print("ENDPROC cr_gl%s" % func_name)
+ print("")
+
+
+ print(';')
+ print('; Aliases')
+ print(';')
+
+ # Now loop over all the functions and take care of any aliases
+ allkeys = apiutil.GetAllFunctions(sys.argv[1]+"/APIspec.txt")
+ for func_name in allkeys:
+ if "omit" in apiutil.ChromiumProps(func_name):
+ continue
+
+ if func_name in keys:
+ # we already processed this function earlier
+ continue
+
+ # alias is the function we're aliasing
+ alias = apiutil.Alias(func_name)
+ if alias:
+ # this dict lookup should never fail (raise an exception)!
+ index = keys.index(alias)
+ print("BEGINPROC_EXPORTED cr_gl%s" % func_name)
+ print("%ifdef RT_ARCH_AMD64")
+ print("\tjmp \t[glim+%d wrt rip wrt ..gotpcrel]" % (8*index))
+ print("%else ; X86")
+ print("\tjmp \t[glim+%d wrt ..gotpc]" % (4*index))
+ print("%endif")
+ print("ENDPROC cr_gl%s" % func_name)
+ print("")
+
+
+ print(';')
+ print('; No-op stubs')
+ print(';')
+
+ # Now generate no-op stub functions
+ for func_name in allkeys:
+ if "stub" in apiutil.ChromiumProps(func_name):
+ print("BEGINPROC_EXPORTED cr_gl%s" % func_name)
+ print("\tleave")
+ print("\tret")
+ print("ENDPROC cr_gl%s" % func_name)
+ print("")
+
+
+GenerateEntrypoints()
+
diff --git a/src/VBox/Additions/common/crOpenGL/SunOS_i386_glxapi_exports.py b/src/VBox/Additions/common/crOpenGL/SunOS_i386_glxapi_exports.py
new file mode 100755
index 00000000..24d7cc53
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/SunOS_i386_glxapi_exports.py
@@ -0,0 +1,103 @@
+"""
+Copyright (C) 2009-2019 Oracle Corporation
+
+This file is part of VirtualBox Open Source Edition (OSE), as
+available from http://www.virtualbox.org. This file is free software;
+you can redistribute it and/or modify it under the terms of the GNU
+General Public License (GPL) as published by the Free Software
+Foundation, in version 2 as it comes in the "COPYING" file of the
+VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+"""
+
+from __future__ import print_function
+import sys
+
+#Note, this should match the fakedri_glxfuncsList.h order
+glx_functions = [
+"CopyContext",
+"UseXFont",
+#"GetDriverConfig",
+"GetProcAddress",
+"QueryExtension",
+"IsDirect",
+"DestroyGLXPbufferSGIX",
+"QueryGLXPbufferSGIX",
+"CreateGLXPixmap",
+"CreateGLXPixmapWithConfigSGIX",
+"QueryContext",
+"CreateContextWithConfigSGIX",
+"SwapBuffers",
+"CreateNewContext",
+"SelectEventSGIX",
+"GetCurrentDrawable",
+"ChooseFBConfig",
+"WaitGL",
+"GetFBConfigs",
+"CreatePixmap",
+"GetSelectedEventSGIX",
+"GetCurrentReadDrawable",
+"GetCurrentDisplay",
+"QueryServerString",
+"CreateWindow",
+"SelectEvent",
+"GetVisualFromFBConfigSGIX",
+"GetFBConfigFromVisualSGIX",
+"QueryDrawable",
+"CreateContext",
+"GetConfig",
+"CreateGLXPbufferSGIX",
+"CreatePbuffer",
+"ChooseFBConfigSGIX",
+"WaitX",
+"GetVisualFromFBConfig",
+#"GetScreenDriver",
+"GetFBConfigAttrib",
+"GetCurrentContext",
+"GetClientString",
+"DestroyPixmap",
+"MakeCurrent",
+"DestroyContext",
+"GetProcAddressARB",
+"GetSelectedEvent",
+"DestroyPbuffer",
+"DestroyWindow",
+"DestroyGLXPixmap",
+"QueryVersion",
+"ChooseVisual",
+"MakeContextCurrent",
+"QueryExtensionsString",
+"GetFBConfigAttribSGIX",
+"FreeMemoryMESA",
+"QueryContextInfoEXT",
+"ImportContextEXT",
+"GetContextIDEXT",
+"MakeCurrentReadSGI",
+"AllocateMemoryMESA",
+"GetMemoryOffsetMESA",
+"CreateGLXPixmapMESA",
+"GetCurrentDisplayEXT",
+"FreeContextEXT"
+];
+
+print('%include "iprt/asmdefs.mac"')
+print("")
+print("%ifdef RT_ARCH_AMD64")
+print("extern glxim")
+print("%else ; X86")
+print("extern glxim")
+print("%endif")
+print("")
+
+for index in range(len(glx_functions)):
+ func_name = glx_functions[index]
+
+ print("BEGINPROC_EXPORTED vbox_glX%s" % func_name)
+ print("%ifdef RT_ARCH_AMD64")
+ print("\tjmp \t[glxim+%d wrt rip wrt ..gotpcrel]" % (8*index))
+ print("%else ; X86")
+ print("\tjmp \t[glxim+%d wrt ..gotpc]" % (4*index))
+ print("%endif")
+ print("ENDPROC vbox_glX%s" % func_name)
+ print("")
+
diff --git a/src/VBox/Additions/common/crOpenGL/VBoxCROGL.rc b/src/VBox/Additions/common/crOpenGL/VBoxCROGL.rc
new file mode 100644
index 00000000..1cafaca7
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/VBoxCROGL.rc
@@ -0,0 +1,70 @@
+/* $Id: VBoxCROGL.rc $ */
+/** @file
+ * VBoxCROGL - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2008-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_RC_FILE_VERSION
+ PRODUCTVERSION VBOX_RC_FILE_VERSION
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS VBOX_RC_FILE_FLAGS
+ FILEFLAGS VBOX_RC_FILE_FLAGS
+ FILEOS VBOX_RC_FILE_OS
+ FILETYPE VBOX_RC_TYPE_DRV
+ FILESUBTYPE VFT2_DRV_DISPLAY
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "VirtualBox crOpenGL ICD\0"
+ VALUE "InternalName", "VBoxCROGL\0"
+#ifdef VBOX_WDDM_WOW64
+ VALUE "OriginalFilename", "VBoxCROGL-x86.dll\0"
+#else
+ VALUE "OriginalFilename", "VBoxCROGL.dll\0"
+#endif
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileVersion", VBOX_RC_FILE_VERSION_STR
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "ProductName", VBOX_RC_PRODUCT_NAME_GA_STR
+ VALUE "ProductVersion", VBOX_RC_PRODUCT_VERSION_STR
+ VBOX_RC_MORE_STRINGS
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+1 RCDATA
+BEGIN
+// Machine dependent parameters
+ 17, // Height of vertical thumb
+ 17, // Width of horizontal thumb
+ 2, // Icon horiz compression factor
+ 2, // Icon vert compression factor
+ 1, // Cursor horz compression factor
+ 1, // Cursor vert compression factor
+ 0, // Kanji window height
+ 1, // cxBorder (thickness of vertical lines)
+ 1 // cyBorder (thickness of horizontal lines)
+END
diff --git a/src/VBox/Additions/common/crOpenGL/VBoxICDList.h b/src/VBox/Additions/common/crOpenGL/VBoxICDList.h
new file mode 100644
index 00000000..dcc901da
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/VBoxICDList.h
@@ -0,0 +1,385 @@
+/* $Id: VBoxICDList.h $ */
+/** @file
+ * VirtualBox Windows NT/2000/XP guest OpenGL ICD
+ */
+
+/*
+ * Copyright (C) 2006-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.1
+ *
+ * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * File name: icd.c
+ * Author: Gregor Anich
+ *
+ * ICD (Installable Client Driver) interface.
+ * Based on the windows GDI/WGL driver.
+ */
+
+ICD_ENTRY(NewList) /* 0 */
+ICD_ENTRY(EndList) /* 1 */
+ICD_ENTRY(CallList) /* 2 */
+ICD_ENTRY(CallLists) /* 3 */
+ICD_ENTRY(DeleteLists) /* 4 */
+ICD_ENTRY(GenLists) /* 5 */
+ICD_ENTRY(ListBase) /* 6 */
+ICD_ENTRY(Begin) /* 7 */
+ICD_ENTRY(Bitmap) /* 8 */
+ICD_ENTRY(Color3b) /* 9 */
+ICD_ENTRY(Color3bv) /* 10 */
+ICD_ENTRY(Color3d) /* 11 */
+ICD_ENTRY(Color3dv) /* 12 */
+ICD_ENTRY(Color3f) /* 13 */
+ICD_ENTRY(Color3fv) /* 14 */
+ICD_ENTRY(Color3i) /* 15 */
+ICD_ENTRY(Color3iv) /* 16 */
+ICD_ENTRY(Color3s) /* 17 */
+ICD_ENTRY(Color3sv) /* 18 */
+ICD_ENTRY(Color3ub) /* 19 */
+ICD_ENTRY(Color3ubv) /* 20 */
+ICD_ENTRY(Color3ui) /* 21 */
+ICD_ENTRY(Color3uiv) /* 22 */
+ICD_ENTRY(Color3us) /* 23 */
+ICD_ENTRY(Color3usv) /* 24 */
+ICD_ENTRY(Color4b) /* 25 */
+ICD_ENTRY(Color4bv) /* 26 */
+ICD_ENTRY(Color4d) /* 27 */
+ICD_ENTRY(Color4dv) /* 28 */
+ICD_ENTRY(Color4f) /* 29 */
+ICD_ENTRY(Color4fv) /* 30 */
+ICD_ENTRY(Color4i) /* 31 */
+ICD_ENTRY(Color4iv) /* 32 */
+ICD_ENTRY(Color4s) /* 33 */
+ICD_ENTRY(Color4sv) /* 34 */
+ICD_ENTRY(Color4ub) /* 35 */
+ICD_ENTRY(Color4ubv) /* 36 */
+ICD_ENTRY(Color4ui) /* 37 */
+ICD_ENTRY(Color4uiv) /* 38 */
+ICD_ENTRY(Color4us) /* 39 */
+ICD_ENTRY(Color4usv) /* 40 */
+ICD_ENTRY(EdgeFlag) /* 41 */
+ICD_ENTRY(EdgeFlagv) /* 42 */
+ICD_ENTRY(End) /* 43 */
+ICD_ENTRY(Indexd) /* 44 */
+ICD_ENTRY(Indexdv) /* 45 */
+ICD_ENTRY(Indexf) /* 46 */
+ICD_ENTRY(Indexfv) /* 47 */
+ICD_ENTRY(Indexi) /* 48 */
+ICD_ENTRY(Indexiv) /* 49 */
+ICD_ENTRY(Indexs) /* 50 */
+ICD_ENTRY(Indexsv) /* 51 */
+ICD_ENTRY(Normal3b) /* 52 */
+ICD_ENTRY(Normal3bv) /* 53 */
+ICD_ENTRY(Normal3d) /* 54 */
+ICD_ENTRY(Normal3dv) /* 55 */
+ICD_ENTRY(Normal3f) /* 56 */
+ICD_ENTRY(Normal3fv) /* 57 */
+ICD_ENTRY(Normal3i) /* 58 */
+ICD_ENTRY(Normal3iv) /* 59 */
+ICD_ENTRY(Normal3s) /* 60 */
+ICD_ENTRY(Normal3sv) /* 61 */
+ICD_ENTRY(RasterPos2d) /* 62 */
+ICD_ENTRY(RasterPos2dv) /* 63 */
+ICD_ENTRY(RasterPos2f) /* 64 */
+ICD_ENTRY(RasterPos2fv) /* 65 */
+ICD_ENTRY(RasterPos2i) /* 66 */
+ICD_ENTRY(RasterPos2iv) /* 67 */
+ICD_ENTRY(RasterPos2s) /* 68 */
+ICD_ENTRY(RasterPos2sv) /* 69 */
+ICD_ENTRY(RasterPos3d) /* 70 */
+ICD_ENTRY(RasterPos3dv) /* 71 */
+ICD_ENTRY(RasterPos3f) /* 72 */
+ICD_ENTRY(RasterPos3fv) /* 73 */
+ICD_ENTRY(RasterPos3i) /* 74 */
+ICD_ENTRY(RasterPos3iv) /* 75 */
+ICD_ENTRY(RasterPos3s) /* 76 */
+ICD_ENTRY(RasterPos3sv) /* 77 */
+ICD_ENTRY(RasterPos4d) /* 78 */
+ICD_ENTRY(RasterPos4dv) /* 79 */
+ICD_ENTRY(RasterPos4f) /* 80 */
+ICD_ENTRY(RasterPos4fv) /* 81 */
+ICD_ENTRY(RasterPos4i) /* 82 */
+ICD_ENTRY(RasterPos4iv) /* 83 */
+ICD_ENTRY(RasterPos4s) /* 84 */
+ICD_ENTRY(RasterPos4sv) /* 85 */
+ICD_ENTRY(Rectd) /* 86 */
+ICD_ENTRY(Rectdv) /* 87 */
+ICD_ENTRY(Rectf) /* 88 */
+ICD_ENTRY(Rectfv) /* 89 */
+ICD_ENTRY(Recti) /* 90 */
+ICD_ENTRY(Rectiv) /* 91 */
+ICD_ENTRY(Rects) /* 92 */
+ICD_ENTRY(Rectsv) /* 93 */
+ICD_ENTRY(TexCoord1d) /* 94 */
+ICD_ENTRY(TexCoord1dv) /* 95 */
+ICD_ENTRY(TexCoord1f) /* 96 */
+ICD_ENTRY(TexCoord1fv) /* 97 */
+ICD_ENTRY(TexCoord1i) /* 98 */
+ICD_ENTRY(TexCoord1iv) /* 99 */
+ICD_ENTRY(TexCoord1s) /* 100 */
+ICD_ENTRY(TexCoord1sv) /* 101 */
+ICD_ENTRY(TexCoord2d) /* 102 */
+ICD_ENTRY(TexCoord2dv) /* 103 */
+ICD_ENTRY(TexCoord2f) /* 104 */
+ICD_ENTRY(TexCoord2fv) /* 105 */
+ICD_ENTRY(TexCoord2i) /* 106 */
+ICD_ENTRY(TexCoord2iv) /* 107 */
+ICD_ENTRY(TexCoord2s) /* 108 */
+ICD_ENTRY(TexCoord2sv) /* 109 */
+ICD_ENTRY(TexCoord3d) /* 110 */
+ICD_ENTRY(TexCoord3dv) /* 111 */
+ICD_ENTRY(TexCoord3f) /* 112 */
+ICD_ENTRY(TexCoord3fv) /* 113 */
+ICD_ENTRY(TexCoord3i) /* 114 */
+ICD_ENTRY(TexCoord3iv) /* 115 */
+ICD_ENTRY(TexCoord3s) /* 116 */
+ICD_ENTRY(TexCoord3sv) /* 117 */
+ICD_ENTRY(TexCoord4d) /* 118 */
+ICD_ENTRY(TexCoord4dv) /* 119 */
+ICD_ENTRY(TexCoord4f) /* 120 */
+ICD_ENTRY(TexCoord4fv) /* 121 */
+ICD_ENTRY(TexCoord4i) /* 122 */
+ICD_ENTRY(TexCoord4iv) /* 123 */
+ICD_ENTRY(TexCoord4s) /* 124 */
+ICD_ENTRY(TexCoord4sv) /* 125 */
+ICD_ENTRY(Vertex2d) /* 126 */
+ICD_ENTRY(Vertex2dv) /* 127 */
+ICD_ENTRY(Vertex2f) /* 128 */
+ICD_ENTRY(Vertex2fv) /* 129 */
+ICD_ENTRY(Vertex2i) /* 130 */
+ICD_ENTRY(Vertex2iv) /* 131 */
+ICD_ENTRY(Vertex2s) /* 132 */
+ICD_ENTRY(Vertex2sv) /* 133 */
+ICD_ENTRY(Vertex3d) /* 134 */
+ICD_ENTRY(Vertex3dv) /* 135 */
+ICD_ENTRY(Vertex3f) /* 136 */
+ICD_ENTRY(Vertex3fv) /* 137 */
+ICD_ENTRY(Vertex3i) /* 138 */
+ICD_ENTRY(Vertex3iv) /* 139 */
+ICD_ENTRY(Vertex3s) /* 140 */
+ICD_ENTRY(Vertex3sv) /* 141 */
+ICD_ENTRY(Vertex4d) /* 142 */
+ICD_ENTRY(Vertex4dv) /* 143 */
+ICD_ENTRY(Vertex4f) /* 144 */
+ICD_ENTRY(Vertex4fv) /* 145 */
+ICD_ENTRY(Vertex4i) /* 146 */
+ICD_ENTRY(Vertex4iv) /* 147 */
+ICD_ENTRY(Vertex4s) /* 148 */
+ICD_ENTRY(Vertex4sv) /* 149 */
+ICD_ENTRY(ClipPlane) /* 150 */
+ICD_ENTRY(ColorMaterial) /* 151 */
+ICD_ENTRY(CullFace) /* 152 */
+ICD_ENTRY(Fogf) /* 153 */
+ICD_ENTRY(Fogfv) /* 154 */
+ICD_ENTRY(Fogi) /* 155 */
+ICD_ENTRY(Fogiv) /* 156 */
+ICD_ENTRY(FrontFace) /* 157 */
+ICD_ENTRY(Hint) /* 158 */
+ICD_ENTRY(Lightf) /* 159 */
+ICD_ENTRY(Lightfv) /* 160 */
+ICD_ENTRY(Lighti) /* 161 */
+ICD_ENTRY(Lightiv) /* 162 */
+ICD_ENTRY(LightModelf) /* 163 */
+ICD_ENTRY(LightModelfv) /* 164 */
+ICD_ENTRY(LightModeli) /* 165 */
+ICD_ENTRY(LightModeliv) /* 166 */
+ICD_ENTRY(LineStipple) /* 167 */
+ICD_ENTRY(LineWidth) /* 168 */
+ICD_ENTRY(Materialf) /* 169 */
+ICD_ENTRY(Materialfv) /* 170 */
+ICD_ENTRY(Materiali) /* 171 */
+ICD_ENTRY(Materialiv) /* 172 */
+ICD_ENTRY(PointSize) /* 173 */
+ICD_ENTRY(PolygonMode) /* 174 */
+ICD_ENTRY(PolygonStipple) /* 175 */
+ICD_ENTRY(Scissor) /* 176 */
+ICD_ENTRY(ShadeModel) /* 177 */
+ICD_ENTRY(TexParameterf) /* 178 */
+ICD_ENTRY(TexParameterfv) /* 179 */
+ICD_ENTRY(TexParameteri) /* 180 */
+ICD_ENTRY(TexParameteriv) /* 181 */
+ICD_ENTRY(TexImage1D) /* 182 */
+ICD_ENTRY(TexImage2D) /* 183 */
+ICD_ENTRY(TexEnvf) /* 184 */
+ICD_ENTRY(TexEnvfv) /* 185 */
+ICD_ENTRY(TexEnvi) /* 186 */
+ICD_ENTRY(TexEnviv) /* 187 */
+ICD_ENTRY(TexGend) /* 188 */
+ICD_ENTRY(TexGendv) /* 189 */
+ICD_ENTRY(TexGenf) /* 190 */
+ICD_ENTRY(TexGenfv) /* 191 */
+ICD_ENTRY(TexGeni) /* 192 */
+ICD_ENTRY(TexGeniv) /* 193 */
+ICD_ENTRY(FeedbackBuffer) /* 194 */
+ICD_ENTRY(SelectBuffer) /* 195 */
+ICD_ENTRY(RenderMode) /* 196 */
+ICD_ENTRY(InitNames) /* 197 */
+ICD_ENTRY(LoadName) /* 198 */
+ICD_ENTRY(PassThrough) /* 199 */
+ICD_ENTRY(PopName) /* 200 */
+ICD_ENTRY(PushName) /* 201 */
+ICD_ENTRY(DrawBuffer) /* 202 */
+ICD_ENTRY(Clear) /* 203 */
+ICD_ENTRY(ClearAccum) /* 204 */
+ICD_ENTRY(ClearIndex) /* 205 */
+ICD_ENTRY(ClearColor) /* 206 */
+ICD_ENTRY(ClearStencil) /* 207 */
+ICD_ENTRY(ClearDepth) /* 208 */
+ICD_ENTRY(StencilMask) /* 209 */
+ICD_ENTRY(ColorMask) /* 210 */
+ICD_ENTRY(DepthMask) /* 211 */
+ICD_ENTRY(IndexMask) /* 212 */
+ICD_ENTRY(Accum) /* 213 */
+ICD_ENTRY(Disable) /* 214 */
+ICD_ENTRY(Enable) /* 215 */
+ICD_ENTRY(Finish) /* 216 */
+ICD_ENTRY(Flush) /* 217 */
+ICD_ENTRY(PopAttrib) /* 218 */
+ICD_ENTRY(PushAttrib) /* 219 */
+ICD_ENTRY(Map1d) /* 220 */
+ICD_ENTRY(Map1f) /* 221 */
+ICD_ENTRY(Map2d) /* 222 */
+ICD_ENTRY(Map2f) /* 223 */
+ICD_ENTRY(MapGrid1d) /* 224 */
+ICD_ENTRY(MapGrid1f) /* 225 */
+ICD_ENTRY(MapGrid2d) /* 226 */
+ICD_ENTRY(MapGrid2f) /* 227 */
+ICD_ENTRY(EvalCoord1d) /* 228 */
+ICD_ENTRY(EvalCoord1dv) /* 229 */
+ICD_ENTRY(EvalCoord1f) /* 230 */
+ICD_ENTRY(EvalCoord1fv) /* 231 */
+ICD_ENTRY(EvalCoord2d) /* 232 */
+ICD_ENTRY(EvalCoord2dv) /* 233 */
+ICD_ENTRY(EvalCoord2f) /* 234 */
+ICD_ENTRY(EvalCoord2fv) /* 235 */
+ICD_ENTRY(EvalMesh1) /* 236 */
+ICD_ENTRY(EvalPoint1) /* 237 */
+ICD_ENTRY(EvalMesh2) /* 238 */
+ICD_ENTRY(EvalPoint2) /* 239 */
+ICD_ENTRY(AlphaFunc) /* 240 */
+ICD_ENTRY(BlendFunc) /* 241 */
+ICD_ENTRY(LogicOp) /* 242 */
+ICD_ENTRY(StencilFunc) /* 243 */
+ICD_ENTRY(StencilOp) /* 244 */
+ICD_ENTRY(DepthFunc) /* 245 */
+ICD_ENTRY(PixelZoom) /* 246 */
+ICD_ENTRY(PixelTransferf) /* 247 */
+ICD_ENTRY(PixelTransferi) /* 248 */
+ICD_ENTRY(PixelStoref) /* 249 */
+ICD_ENTRY(PixelStorei) /* 250 */
+ICD_ENTRY(PixelMapfv) /* 251 */
+ICD_ENTRY(PixelMapuiv) /* 252 */
+ICD_ENTRY(PixelMapusv) /* 253 */
+ICD_ENTRY(ReadBuffer) /* 254 */
+ICD_ENTRY(CopyPixels) /* 255 */
+ICD_ENTRY(ReadPixels) /* 256 */
+ICD_ENTRY(DrawPixels) /* 257 */
+ICD_ENTRY(GetBooleanv) /* 258 */
+ICD_ENTRY(GetClipPlane) /* 259 */
+ICD_ENTRY(GetDoublev) /* 260 */
+ICD_ENTRY(GetError) /* 261 */
+ICD_ENTRY(GetFloatv) /* 262 */
+ICD_ENTRY(GetIntegerv) /* 263 */
+ICD_ENTRY(GetLightfv) /* 264 */
+ICD_ENTRY(GetLightiv) /* 265 */
+ICD_ENTRY(GetMapdv) /* 266 */
+ICD_ENTRY(GetMapfv) /* 267 */
+ICD_ENTRY(GetMapiv) /* 268 */
+ICD_ENTRY(GetMaterialfv) /* 269 */
+ICD_ENTRY(GetMaterialiv) /* 270 */
+ICD_ENTRY(GetPixelMapfv) /* 271 */
+ICD_ENTRY(GetPixelMapuiv) /* 272 */
+ICD_ENTRY(GetPixelMapusv) /* 273 */
+ICD_ENTRY(GetPolygonStipple) /* 274 */
+ICD_ENTRY(GetString) /* 275 */
+ICD_ENTRY(GetTexEnvfv) /* 276 */
+ICD_ENTRY(GetTexEnviv) /* 277 */
+ICD_ENTRY(GetTexGendv) /* 278 */
+ICD_ENTRY(GetTexGenfv) /* 279 */
+ICD_ENTRY(GetTexGeniv) /* 280 */
+ICD_ENTRY(GetTexImage) /* 281 */
+ICD_ENTRY(GetTexParameterfv) /* 282 */
+ICD_ENTRY(GetTexParameteriv) /* 283 */
+ICD_ENTRY(GetTexLevelParameterfv) /* 284 */
+ICD_ENTRY(GetTexLevelParameteriv) /* 285 */
+ICD_ENTRY(IsEnabled) /* 286 */
+ICD_ENTRY(IsList) /* 287 */
+ICD_ENTRY(DepthRange) /* 288 */
+ICD_ENTRY(Frustum) /* 289 */
+ICD_ENTRY(LoadIdentity) /* 290 */
+ICD_ENTRY(LoadMatrixf) /* 291 */
+ICD_ENTRY(LoadMatrixd) /* 292 */
+ICD_ENTRY(MatrixMode) /* 293 */
+ICD_ENTRY(MultMatrixf) /* 294 */
+ICD_ENTRY(MultMatrixd) /* 295 */
+ICD_ENTRY(Ortho) /* 296 */
+ICD_ENTRY(PopMatrix) /* 297 */
+ICD_ENTRY(PushMatrix) /* 298 */
+ICD_ENTRY(Rotated) /* 299 */
+ICD_ENTRY(Rotatef) /* 300 */
+ICD_ENTRY(Scaled) /* 301 */
+ICD_ENTRY(Scalef) /* 302 */
+ICD_ENTRY(Translated) /* 303 */
+ICD_ENTRY(Translatef) /* 304 */
+ICD_ENTRY(Viewport) /* 305 */
+ICD_ENTRY(ArrayElement) /* 306 */
+ICD_ENTRY(BindTexture) /* 307 */
+ICD_ENTRY(ColorPointer) /* 308 */
+ICD_ENTRY(DisableClientState) /* 309 */
+ICD_ENTRY(DrawArrays) /* 310 */
+ICD_ENTRY(DrawElements) /* 311 */
+ICD_ENTRY(EdgeFlagPointer) /* 312 */
+ICD_ENTRY(EnableClientState) /* 313 */
+ICD_ENTRY(IndexPointer) /* 314 */
+ICD_ENTRY(Indexub) /* 315 */
+ICD_ENTRY(Indexubv) /* 316 */
+ICD_ENTRY(InterleavedArrays) /* 317 */
+ICD_ENTRY(NormalPointer) /* 318 */
+ICD_ENTRY(PolygonOffset) /* 319 */
+ICD_ENTRY(TexCoordPointer) /* 320 */
+ICD_ENTRY(VertexPointer) /* 321 */
+ICD_ENTRY(AreTexturesResident) /* 322 */
+ICD_ENTRY(CopyTexImage1D) /* 323 */
+ICD_ENTRY(CopyTexImage2D) /* 324 */
+ICD_ENTRY(CopyTexSubImage1D) /* 325 */
+ICD_ENTRY(CopyTexSubImage2D) /* 326 */
+ICD_ENTRY(DeleteTextures) /* 327 */
+ICD_ENTRY(GenTextures) /* 328 */
+ICD_ENTRY(GetPointerv) /* 329 */
+ICD_ENTRY(IsTexture) /* 330 */
+ICD_ENTRY(PrioritizeTextures) /* 331 */
+ICD_ENTRY(TexSubImage1D) /* 332 */
+ICD_ENTRY(TexSubImage2D) /* 333 */
+ICD_ENTRY(PopClientAttrib) /* 334 */
+ICD_ENTRY(PushClientAttrib) /* 335 */
diff --git a/src/VBox/Additions/common/crOpenGL/alias_exports.py b/src/VBox/Additions/common/crOpenGL/alias_exports.py
new file mode 100644
index 00000000..5d16139a
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/alias_exports.py
@@ -0,0 +1,168 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+aliases = [
+ # GL_ARB_multitexture / OpenGL 1.2.1
+ ('ActiveTexture', 'ActiveTextureARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('ClientActiveTexture', 'ClientActiveTextureARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord1d', 'MultiTexCoord1dARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord1dv','MultiTexCoord1dvARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord1f', 'MultiTexCoord1fARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord1fv','MultiTexCoord1fvARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord1i', 'MultiTexCoord1iARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord1iv','MultiTexCoord1ivARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord1s', 'MultiTexCoord1sARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord1sv','MultiTexCoord1svARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord2d', 'MultiTexCoord2dARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord2dv','MultiTexCoord2dvARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord2f', 'MultiTexCoord2fARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord2fv','MultiTexCoord2fvARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord2i', 'MultiTexCoord2iARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord2iv','MultiTexCoord2ivARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord2s', 'MultiTexCoord2sARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord2sv','MultiTexCoord2svARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord3d', 'MultiTexCoord3dARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord3dv','MultiTexCoord3dvARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord3f', 'MultiTexCoord3fARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord3fv','MultiTexCoord3fvARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord3i', 'MultiTexCoord3iARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord3iv','MultiTexCoord3ivARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord3s', 'MultiTexCoord3sARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord3sv','MultiTexCoord3svARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord4d', 'MultiTexCoord4dARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord4dv','MultiTexCoord4dvARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord4f', 'MultiTexCoord4fARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord4fv','MultiTexCoord4fvARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord4i', 'MultiTexCoord4iARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord4iv','MultiTexCoord4ivARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord4s', 'MultiTexCoord4sARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ ('MultiTexCoord4sv','MultiTexCoord4svARB', 'ARB_multitexture', 'CR_OPENGL_VERSION_1_2_1'),
+ # GL_ARB_transpose_matrix / OpenGL 1.3
+ ('LoadTransposeMatrixf','LoadTransposeMatrixfARB', 'ARB_transpose_matrix', 'CR_OPENGL_VERSION_1_3'),
+ ('LoadTransposeMatrixd','LoadTransposeMatrixdARB', 'ARB_transpose_matrix', 'CR_OPENGL_VERSION_1_3'),
+ ('MultTransposeMatrixf','MultTransposeMatrixfARB', 'ARB_transpose_matrix', 'CR_OPENGL_VERSION_1_3'),
+ ('MultTransposeMatrixd','MultTransposeMatrixdARB', 'ARB_transpose_matrix', 'CR_OPENGL_VERSION_1_3'),
+ # GL_ARB_texture_compression / OpenGL 1.3
+ ('CompressedTexImage3D', 'CompressedTexImage3DARB', 'ARB_texture_compression', 'CR_OPENGL_VERSION_1_3'),
+ ('CompressedTexImage2D', 'CompressedTexImage2DARB', 'ARB_texture_compression', 'CR_OPENGL_VERSION_1_3'),
+ ('CompressedTexImage1D', 'CompressedTexImage1DARB', 'ARB_texture_compression', 'CR_OPENGL_VERSION_1_3'),
+ ('CompressedTexSubImage3D', 'CompressedTexSubImage3DARB', 'ARB_texture_compression', 'CR_OPENGL_VERSION_1_3'),
+ ('CompressedTexSubImage2D', 'CompressedTexSubImage2DARB', 'ARB_texture_compression', 'CR_OPENGL_VERSION_1_3'),
+ ('CompressedTexSubImage1D', 'CompressedTexSubImage1DARB', 'ARB_texture_compression', 'CR_OPENGL_VERSION_1_3'),
+ ('GetCompressedTexImage', 'GetCompressedTexImageARB', 'ARB_texture_compression', 'CR_OPENGL_VERSION_1_3'),
+ # GL_ARB_multisample / OpenGL 1.3
+ ('SampleCoverage', 'SampleCoverageARB', 'ARB_multisample', 'CR_OPENGL_VERSION_1_3'),
+ # GL_ARB_window_pos / OpenGL 1.4
+ ('WindowPos2d', 'WindowPos2dARB', 'ARB_window_pos', 'CR_OPENGL_VERSION_1_4'),
+
+ ('WindowPos2dv', 'WindowPos2dvARB', 'ARB_window_pos', 'CR_OPENGL_VERSION_1_4'),
+ ('WindowPos2f', 'WindowPos2fARB', 'ARB_window_pos', 'CR_OPENGL_VERSION_1_4'),
+ ('WindowPos2fv', 'WindowPos2fvARB', 'ARB_window_pos', 'CR_OPENGL_VERSION_1_4'),
+ ('WindowPos2i', 'WindowPos2iARB', 'ARB_window_pos', 'CR_OPENGL_VERSION_1_4'),
+ ('WindowPos2iv', 'WindowPos2ivARB', 'ARB_window_pos', 'CR_OPENGL_VERSION_1_4'),
+ ('WindowPos2s', 'WindowPos2sARB', 'ARB_window_pos', 'CR_OPENGL_VERSION_1_4'),
+ ('WindowPos2sv', 'WindowPos2svARB', 'ARB_window_pos', 'CR_OPENGL_VERSION_1_4'),
+ ('WindowPos3d', 'WindowPos3dARB', 'ARB_window_pos', 'CR_OPENGL_VERSION_1_4'),
+ ('WindowPos3dv', 'WindowPos3dvARB', 'ARB_window_pos', 'CR_OPENGL_VERSION_1_4'),
+ ('WindowPos3f', 'WindowPos3fARB', 'ARB_window_pos', 'CR_OPENGL_VERSION_1_4'),
+ ('WindowPos3fv', 'WindowPos3fvARB', 'ARB_window_pos', 'CR_OPENGL_VERSION_1_4'),
+ ('WindowPos3i', 'WindowPos3iARB', 'ARB_window_pos', 'CR_OPENGL_VERSION_1_4'),
+ ('WindowPos3iv', 'WindowPos3ivARB', 'ARB_window_pos', 'CR_OPENGL_VERSION_1_4'),
+ ('WindowPos3s', 'WindowPos3sARB', 'ARB_window_pos', 'CR_OPENGL_VERSION_1_4'),
+ ('WindowPos3sv', 'WindowPos3svARB', 'ARB_window_pos', 'CR_OPENGL_VERSION_1_4'),
+ # GL_ARB_point_parameters / OpenGL 1.4
+ ('PointParameterf', 'PointParameterfARB', 'ARB_point_parameters', 'CR_OPENGL_VERSION_1_4'),
+ ('PointParameterfv', 'PointParameterfvARB', 'ARB_point_parameters', 'CR_OPENGL_VERSION_1_4'),
+ # GL_EXT_blend_color / OpenGL 1.4
+ ('BlendColor', 'BlendColorEXT', 'EXT_blend_color', 'CR_OPENGL_VERSION_1_4'),
+ # GL_EXT_blend_func_separate / OpenGL 1.4
+ ('BlendFuncSeparate', 'BlendFuncSeparateEXT', 'EXT_blend_func_separate', 'CR_OPENGL_VERSION_1_4'),
+ # GL_EXT_blend_equation / OpenGL 1.4
+ ('BlendEquation', 'BlendEquationEXT', 'EXT_blend_equation', 'CR_OPENGL_VERSION_1_4'),
+ # GL_EXT_multi_draw_arrays / OpenGL 1.4
+ ('MultiDrawArrays', 'MultiDrawArraysEXT', 'EXT_multi_draw_arrays', 'CR_OPENGL_VERSION_1_4'),
+ ('MultiDrawElements', 'MultiDrawElementsEXT', 'EXT_multi_draw_arrays', 'CR_OPENGL_VERSION_1_4'),
+ # GL_EXT_secondary_color / OpenGL 1.4
+ ('SecondaryColor3b', 'SecondaryColor3bEXT', 'EXT_secondary_color', 'CR_OPENGL_VERSION_1_4'),
+ ('SecondaryColor3bv', 'SecondaryColor3bvEXT', 'EXT_secondary_color', 'CR_OPENGL_VERSION_1_4'),
+ ('SecondaryColor3d', 'SecondaryColor3dEXT', 'EXT_secondary_color', 'CR_OPENGL_VERSION_1_4'),
+ ('SecondaryColor3dv', 'SecondaryColor3dvEXT', 'EXT_secondary_color', 'CR_OPENGL_VERSION_1_4'),
+ ('SecondaryColor3f', 'SecondaryColor3fEXT', 'EXT_secondary_color', 'CR_OPENGL_VERSION_1_4'),
+ ('SecondaryColor3fv', 'SecondaryColor3fvEXT', 'EXT_secondary_color', 'CR_OPENGL_VERSION_1_4'),
+ ('SecondaryColor3i', 'SecondaryColor3iEXT', 'EXT_secondary_color', 'CR_OPENGL_VERSION_1_4'),
+ ('SecondaryColor3iv', 'SecondaryColor3ivEXT', 'EXT_secondary_color', 'CR_OPENGL_VERSION_1_4'),
+ ('SecondaryColor3s', 'SecondaryColor3sEXT', 'EXT_secondary_color', 'CR_OPENGL_VERSION_1_4'),
+ ('SecondaryColor3sv', 'SecondaryColor3svEXT', 'EXT_secondary_color', 'CR_OPENGL_VERSION_1_4'),
+ ('SecondaryColor3ub', 'SecondaryColor3ubEXT', 'EXT_secondary_color', 'CR_OPENGL_VERSION_1_4'),
+ ('SecondaryColor3ubv', 'SecondaryColor3ubvEXT', 'EXT_secondary_color', 'CR_OPENGL_VERSION_1_4'),
+ ('SecondaryColor3ui', 'SecondaryColor3uiEXT', 'EXT_secondary_color', 'CR_OPENGL_VERSION_1_4'),
+ ('SecondaryColor3uiv', 'SecondaryColor3uivEXT', 'EXT_secondary_color', 'CR_OPENGL_VERSION_1_4'),
+ ('SecondaryColor3us', 'SecondaryColor3usEXT', 'EXT_secondary_color', 'CR_OPENGL_VERSION_1_4'),
+ ('SecondaryColor3usv', 'SecondaryColor3usvEXT', 'EXT_secondary_color', 'CR_OPENGL_VERSION_1_4'),
+ ('SecondaryColorPointer', 'SecondaryColorPointerEXT', 'EXT_secondary_color', 'CR_OPENGL_VERSION_1_4'),
+ # GL_EXT_fog_coord / OpenGL 1.4
+ ('FogCoordf', 'FogCoordfEXT', 'EXT_fog_coord', 'CR_OPENGL_VERSION_1_4'),
+ ('FogCoordfv', 'FogCoordfvEXT', 'EXT_fog_coord', 'CR_OPENGL_VERSION_1_4'),
+ ('FogCoordd', 'FogCoorddEXT', 'EXT_fog_coord', 'CR_OPENGL_VERSION_1_4'),
+ ('FogCoorddv', 'FogCoorddvEXT', 'EXT_fog_coord', 'CR_OPENGL_VERSION_1_4'),
+ ('FogCoordPointer', 'FogCoordPointerEXT', 'EXT_fog_coord', 'CR_OPENGL_VERSION_1_4'),
+ # GL_EXT_texture_object / OpenGL 1.1
+ ('AreTexturesResidentEXT', 'AreTexturesResident', 'EXT_texture_object', 'CR_OPENGL_VERSION_1_1'),
+ ('BindTextureEXT', 'BindTexture', 'EXT_texture_object', 'CR_OPENGL_VERSION_1_1'),
+ ('DeleteTexturesEXT', 'DeleteTextures', 'EXT_texture_object', 'CR_OPENGL_VERSION_1_1'),
+ ('GenTexturesEXT', 'GenTextures', 'EXT_texture_object', 'CR_OPENGL_VERSION_1_1'),
+ ('IsTextureEXT', 'IsTexture', 'EXT_texture_object', 'CR_OPENGL_VERSION_1_1'),
+ ('PrioritizeTexturesEXT', 'PrioritizeTextures', 'EXT_texture_object', 'CR_OPENGL_VERSION_1_1'),
+ # GL_EXT_texture3D / OpenGL 1.2
+ ('TexSubImage3DEXT', 'TexSubImage3D', 'EXT_texture3D', 'CR_OPENGL_VERSION_1_2'),
+
+ # GL_NV_vertex_program / GL_ARB_vertex_program
+ ('VertexAttrib1sNV', 'VertexAttrib1sARB', 'ARB_vertex_program', ''),
+ ('VertexAttrib1svNV', 'VertexAttrib1svARB', 'ARB_vertex_program', ''),
+ ('VertexAttrib1fNV', 'VertexAttrib1fARB', 'ARB_vertex_program', ''),
+ ('VertexAttrib1fvNV', 'VertexAttrib1fvARB', 'ARB_vertex_program', ''),
+ ('VertexAttrib1dNV', 'VertexAttrib1dARB', 'ARB_vertex_program', ''),
+ ('VertexAttrib1dvNV', 'VertexAttrib1dvARB', 'ARB_vertex_program', ''),
+ ('VertexAttrib2sNV', 'VertexAttrib2sARB', 'ARB_vertex_program', ''),
+ ('VertexAttrib2svNV', 'VertexAttrib2svARB', 'ARB_vertex_program', ''),
+ ('VertexAttrib2fNV', 'VertexAttrib2fARB', 'ARB_vertex_program', ''),
+ ('VertexAttrib2fvNV', 'VertexAttrib2fvARB', 'ARB_vertex_program', ''),
+ ('VertexAttrib2dNV', 'VertexAttrib2dARB', 'ARB_vertex_program', ''),
+ ('VertexAttrib2dvNV', 'VertexAttrib2dvARB', 'ARB_vertex_program', ''),
+ ('VertexAttrib3sNV', 'VertexAttrib3sARB', 'ARB_vertex_program', ''),
+ ('VertexAttrib3svNV', 'VertexAttrib3svARB', 'ARB_vertex_program', ''),
+ ('VertexAttrib3fNV', 'VertexAttrib3fARB', 'ARB_vertex_program', ''),
+ ('VertexAttrib3fvNV', 'VertexAttrib3fvARB', 'ARB_vertex_program', ''),
+ ('VertexAttrib3dNV', 'VertexAttrib3dARB', 'ARB_vertex_program', ''),
+ ('VertexAttrib3dvNV', 'VertexAttrib3dvARB', 'ARB_vertex_program', ''),
+ ('VertexAttrib4sNV', 'VertexAttrib4sARB', 'ARB_vertex_program', ''),
+ ('VertexAttrib4svNV', 'VertexAttrib4svARB', 'ARB_vertex_program', ''),
+ ('VertexAttrib4fNV', 'VertexAttrib4fARB', 'ARB_vertex_program', ''),
+ ('VertexAttrib4fvNV', 'VertexAttrib4fvARB', 'ARB_vertex_program', ''),
+ ('VertexAttrib4dNV', 'VertexAttrib4dARB', 'ARB_vertex_program', ''),
+ ('VertexAttrib4dvNV', 'VertexAttrib4dvARB', 'ARB_vertex_program', ''),
+ ('VertexAttrib4ubNV', 'VertexAttrib4NubARB', 'ARB_vertex_program', ''),
+ ('VertexAttrib4ubvNV', 'VertexAttrib4NubvARB', 'ARB_vertex_program', ''),
+ ('DeleteProgramsNV', 'DeleteProgramsARB', 'ARB_vertex_program', ''),
+ ('IsProgramNV', 'IsProgramARB', 'ARB_vertex_program', '')
+]
+
+def AliasMap( func_name ):
+ for (aliased_func_name, real_func_name, ext_define, gl_version) in aliases:
+ if real_func_name == func_name:
+ return aliased_func_name;
+ return None
+
+def ExtDefine( func_name ):
+ for (aliased_func_name, real_func_name, ext_define, gl_version) in aliases:
+ if real_func_name == func_name:
+ return ext_define;
+ return None
+
+def GLversion( func_name ):
+ for (aliased_func_name, real_func_name, ext_define, gl_version) in aliases:
+ if real_func_name == func_name:
+ return gl_version;
+ return None
diff --git a/src/VBox/Additions/common/crOpenGL/array/Makefile.kup b/src/VBox/Additions/common/crOpenGL/array/Makefile.kup
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/array/Makefile.kup
diff --git a/src/VBox/Additions/common/crOpenGL/array/arrayspu.c b/src/VBox/Additions/common/crOpenGL/array/arrayspu.c
new file mode 100644
index 00000000..da230ee5
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/array/arrayspu.c
@@ -0,0 +1,944 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include <stdio.h>
+#include "cr_spu.h"
+#include "cr_error.h"
+#include "state/cr_limits.h"
+#include "arrayspu.h"
+
+ArraySPU array_spu;
+
+#ifdef CHROMIUM_THREADSAFE
+CRmutex _ArrayMutex;
+#endif
+
+static void ARRAYSPU_APIENTRY arrayspu_ArrayElement( GLint index )
+{
+ const CRClientState *c = &(crStateGetCurrent()->client);
+ const CRVertexArrays *array = &(c->array);
+ const GLboolean vpEnabled = crStateGetCurrent()->program.vpEnabled;
+ unsigned char *p;
+ unsigned int unit, attr;
+
+ if (array->e.enabled)
+ {
+ p = array->e.p + index * array->e.stride;
+
+#ifdef CR_ARB_vertex_buffer_object
+ if (array->e.buffer && array->e.buffer->data)
+ {
+ p = (unsigned char *)(array->e.buffer->data) + (unsigned long)p;
+ }
+#endif
+
+ array_spu.self.EdgeFlagv(p);
+ }
+
+ /*
+ * Vertex attribute arrays (GL_NV_vertex_program) have priority over
+ * the conventional vertex arrays.
+ */
+ if (vpEnabled)
+ {
+ for (attr = 1; attr < VERT_ATTRIB_MAX; attr++)
+ {
+ if (array->a[attr].enabled)
+ {
+ GLint *iPtr;
+ p = array->a[attr].p + index * array->a[attr].stride;
+
+#ifdef CR_ARB_vertex_buffer_object
+ if (array->a[attr].buffer && array->a[attr].buffer->data)
+ {
+ p = (unsigned char *)(array->a[attr].buffer->data) + (unsigned long)p;
+ }
+#endif
+
+ switch (array->a[attr].type)
+ {
+ case GL_SHORT:
+ switch (array->a[attr].size)
+ {
+ case 1: array_spu.self.VertexAttrib1svARB(attr, (GLshort *)p); break;
+ case 2: array_spu.self.VertexAttrib2svARB(attr, (GLshort *)p); break;
+ case 3: array_spu.self.VertexAttrib3svARB(attr, (GLshort *)p); break;
+ case 4: array_spu.self.VertexAttrib4svARB(attr, (GLshort *)p); break;
+ }
+ break;
+ case GL_INT:
+ iPtr = (GLint *) p;
+ switch (array->a[attr].size)
+ {
+ case 1: array_spu.self.VertexAttrib1fARB(attr, p[0]); break;
+ case 2: array_spu.self.VertexAttrib2fARB(attr, p[0], p[1]); break;
+ case 3: array_spu.self.VertexAttrib3fARB(attr, p[0], p[1], p[2]); break;
+ case 4: array_spu.self.VertexAttrib4fARB(attr, p[0], p[1], p[2], p[3]); break;
+ }
+ break;
+ case GL_FLOAT:
+ switch (array->a[attr].size)
+ {
+ case 1: array_spu.self.VertexAttrib1fvARB(attr, (GLfloat *)p); break;
+ case 2: array_spu.self.VertexAttrib2fvARB(attr, (GLfloat *)p); break;
+ case 3: array_spu.self.VertexAttrib3fvARB(attr, (GLfloat *)p); break;
+ case 4: array_spu.self.VertexAttrib4fvARB(attr, (GLfloat *)p); break;
+ }
+ break;
+ case GL_DOUBLE:
+ switch (array->a[attr].size)
+ {
+ case 1: array_spu.self.VertexAttrib1dvARB(attr, (GLdouble *)p); break;
+ case 2: array_spu.self.VertexAttrib2dvARB(attr, (GLdouble *)p); break;
+ case 3: array_spu.self.VertexAttrib3dvARB(attr, (GLdouble *)p); break;
+ case 4: array_spu.self.VertexAttrib4dvARB(attr, (GLdouble *)p); break;
+ }
+ break;
+ default:
+ crWarning("Bad datatype for vertex attribute [%d] array: 0x%x\n",
+ attr, array->a[attr].type);
+ }
+ }
+ }
+ }
+
+ /* Now do conventional arrays, unless overridden by generic arrays above */
+ for (unit = 0 ; unit < crStateGetCurrent()->limits.maxTextureUnits ; unit++)
+ {
+ if (array->t[unit].enabled && !(vpEnabled && array->a[VERT_ATTRIB_TEX0+unit].enabled))
+ {
+ p = array->t[unit].p + index * array->t[unit].stride;
+
+#ifdef CR_ARB_vertex_buffer_object
+ if (array->t[unit].buffer && array->t[unit].buffer->data)
+ {
+ p = (unsigned char *)(array->t[unit].buffer->data) + (unsigned long)p;
+ }
+#endif
+
+ switch (array->t[unit].type)
+ {
+ case GL_SHORT:
+ switch (array->t[unit].size)
+ {
+ case 1: array_spu.self.MultiTexCoord1svARB(GL_TEXTURE0_ARB + unit, (GLshort *)p); break;
+ case 2: array_spu.self.MultiTexCoord2svARB(GL_TEXTURE0_ARB + unit, (GLshort *)p); break;
+ case 3: array_spu.self.MultiTexCoord3svARB(GL_TEXTURE0_ARB + unit, (GLshort *)p); break;
+ case 4: array_spu.self.MultiTexCoord4svARB(GL_TEXTURE0_ARB + unit, (GLshort *)p); break;
+ }
+ break;
+ case GL_INT:
+ switch (array->t[unit].size)
+ {
+ case 1: array_spu.self.MultiTexCoord1ivARB(GL_TEXTURE0_ARB + unit, (GLint *)p); break;
+ case 2: array_spu.self.MultiTexCoord2ivARB(GL_TEXTURE0_ARB + unit, (GLint *)p); break;
+ case 3: array_spu.self.MultiTexCoord3ivARB(GL_TEXTURE0_ARB + unit, (GLint *)p); break;
+ case 4: array_spu.self.MultiTexCoord4ivARB(GL_TEXTURE0_ARB + unit, (GLint *)p); break;
+ }
+ break;
+ case GL_FLOAT:
+ switch (array->t[unit].size)
+ {
+ case 1: array_spu.self.MultiTexCoord1fvARB(GL_TEXTURE0_ARB + unit, (GLfloat *)p); break;
+ case 2: array_spu.self.MultiTexCoord2fvARB(GL_TEXTURE0_ARB + unit, (GLfloat *)p); break;
+ case 3: array_spu.self.MultiTexCoord3fvARB(GL_TEXTURE0_ARB + unit, (GLfloat *)p); break;
+ case 4: array_spu.self.MultiTexCoord4fvARB(GL_TEXTURE0_ARB + unit, (GLfloat *)p); break;
+ }
+ break;
+ case GL_DOUBLE:
+ switch (array->t[unit].size)
+ {
+ case 1: array_spu.self.MultiTexCoord1dvARB(GL_TEXTURE0_ARB + unit, (GLdouble *)p); break;
+ case 2: array_spu.self.MultiTexCoord2dvARB(GL_TEXTURE0_ARB + unit, (GLdouble *)p); break;
+ case 3: array_spu.self.MultiTexCoord3dvARB(GL_TEXTURE0_ARB + unit, (GLdouble *)p); break;
+ case 4: array_spu.self.MultiTexCoord4dvARB(GL_TEXTURE0_ARB + unit, (GLdouble *)p); break;
+ }
+ break;
+ }
+ }
+ }
+ if (array->i.enabled)
+ {
+ p = array->i.p + index * array->i.stride;
+
+#ifdef CR_ARB_vertex_buffer_object
+ if (array->i.buffer && array->i.buffer->data)
+ {
+ p = (unsigned char *)(array->i.buffer->data) + (unsigned long)p;
+ }
+#endif
+
+ switch (array->i.type)
+ {
+ case GL_SHORT: array_spu.self.Indexsv((GLshort *)p); break;
+ case GL_INT: array_spu.self.Indexiv((GLint *)p); break;
+ case GL_FLOAT: array_spu.self.Indexfv((GLfloat *)p); break;
+ case GL_DOUBLE: array_spu.self.Indexdv((GLdouble *)p); break;
+ }
+ }
+ if (array->c.enabled && !(vpEnabled && array->a[VERT_ATTRIB_COLOR0].enabled))
+ {
+ p = array->c.p + index * array->c.stride;
+
+#ifdef CR_ARB_vertex_buffer_object
+ if (array->c.buffer && array->c.buffer->data)
+ {
+ p = (unsigned char *)(array->c.buffer->data) + (unsigned long)p;
+ }
+#endif
+
+ switch (array->c.type)
+ {
+ case GL_BYTE:
+ switch (array->c.size)
+ {
+ case 3: array_spu.self.Color3bv((GLbyte *)p); break;
+ case 4: array_spu.self.Color4bv((GLbyte *)p); break;
+ }
+ break;
+ case GL_UNSIGNED_BYTE:
+ switch (array->c.size)
+ {
+ case 3: array_spu.self.Color3ubv((GLubyte *)p); break;
+ case 4: array_spu.self.Color4ubv((GLubyte *)p); break;
+ }
+ break;
+ case GL_SHORT:
+ switch (array->c.size)
+ {
+ case 3: array_spu.self.Color3sv((GLshort *)p); break;
+ case 4: array_spu.self.Color4sv((GLshort *)p); break;
+ }
+ break;
+ case GL_UNSIGNED_SHORT:
+ switch (array->c.size)
+ {
+ case 3: array_spu.self.Color3usv((GLushort *)p); break;
+ case 4: array_spu.self.Color4usv((GLushort *)p); break;
+ }
+ break;
+ case GL_INT:
+ switch (array->c.size)
+ {
+ case 3: array_spu.self.Color3iv((GLint *)p); break;
+ case 4: array_spu.self.Color4iv((GLint *)p); break;
+ }
+ break;
+ case GL_UNSIGNED_INT:
+ switch (array->c.size)
+ {
+ case 3: array_spu.self.Color3uiv((GLuint *)p); break;
+ case 4: array_spu.self.Color4uiv((GLuint *)p); break;
+ }
+ break;
+ case GL_FLOAT:
+ switch (array->c.size)
+ {
+ case 3: array_spu.self.Color3fv((GLfloat *)p); break;
+ case 4: array_spu.self.Color4fv((GLfloat *)p); break;
+ }
+ break;
+ case GL_DOUBLE:
+ switch (array->c.size)
+ {
+ case 3: array_spu.self.Color3dv((GLdouble *)p); break;
+ case 4: array_spu.self.Color4dv((GLdouble *)p); break;
+ }
+ break;
+ }
+ }
+ if (array->n.enabled && !(vpEnabled && array->a[VERT_ATTRIB_NORMAL].enabled))
+ {
+ p = array->n.p + index * array->n.stride;
+
+#ifdef CR_ARB_vertex_buffer_object
+ if (array->n.buffer && array->n.buffer->data)
+ {
+ p = (unsigned char *)(array->n.buffer->data) + (unsigned long)p;
+ }
+#endif
+
+ switch (array->n.type)
+ {
+ case GL_BYTE: array_spu.self.Normal3bv((GLbyte *)p); break;
+ case GL_SHORT: array_spu.self.Normal3sv((GLshort *)p); break;
+ case GL_INT: array_spu.self.Normal3iv((GLint *)p); break;
+ case GL_FLOAT: array_spu.self.Normal3fv((GLfloat *)p); break;
+ case GL_DOUBLE: array_spu.self.Normal3dv((GLdouble *)p); break;
+ }
+ }
+#ifdef CR_EXT_secondary_color
+ if (array->s.enabled && !(vpEnabled && array->a[VERT_ATTRIB_COLOR1].enabled))
+ {
+ p = array->s.p + index * array->s.stride;
+
+#ifdef CR_ARB_vertex_buffer_object
+ if (array->s.buffer && array->s.buffer->data)
+ {
+ p = (unsigned char *)(array->s.buffer->data) + (unsigned long)p;
+ }
+#endif
+
+ switch (array->s.type)
+ {
+ case GL_BYTE:
+ array_spu.self.SecondaryColor3bvEXT((GLbyte *)p); break;
+ case GL_UNSIGNED_BYTE:
+ array_spu.self.SecondaryColor3ubvEXT((GLubyte *)p); break;
+ case GL_SHORT:
+ array_spu.self.SecondaryColor3svEXT((GLshort *)p); break;
+ case GL_UNSIGNED_SHORT:
+ array_spu.self.SecondaryColor3usvEXT((GLushort *)p); break;
+ case GL_INT:
+ array_spu.self.SecondaryColor3ivEXT((GLint *)p); break;
+ case GL_UNSIGNED_INT:
+ array_spu.self.SecondaryColor3uivEXT((GLuint *)p); break;
+ case GL_FLOAT:
+ array_spu.self.SecondaryColor3fvEXT((GLfloat *)p); break;
+ case GL_DOUBLE:
+ array_spu.self.SecondaryColor3dvEXT((GLdouble *)p); break;
+ }
+ }
+#endif // CR_EXT_secondary_color
+#ifdef CR_EXT_fog_coord
+ if (array->f.enabled && !(vpEnabled && array->a[VERT_ATTRIB_FOG].enabled))
+ {
+ p = array->f.p + index * array->f.stride;
+
+#ifdef CR_ARB_vertex_buffer_object
+ if (array->f.buffer && array->f.buffer->data)
+ {
+ p = (unsigned char *)(array->f.buffer->data) + (unsigned long)p;
+ }
+#endif
+
+ array_spu.self.FogCoordfEXT( *((GLfloat *) p) );
+ }
+#endif // CR_EXT_fog_coord
+
+ /* Need to do attrib[0] / vertex position last */
+ if (array->a[VERT_ATTRIB_POS].enabled) {
+ GLint *iPtr;
+ p = array->a[VERT_ATTRIB_POS].p + index * array->a[VERT_ATTRIB_POS].stride;
+
+#ifdef CR_ARB_vertex_buffer_object
+ if (array->a[VERT_ATTRIB_POS].buffer && array->a[VERT_ATTRIB_POS].buffer->data)
+ {
+ p = (unsigned char *)(array->a[VERT_ATTRIB_POS].buffer->data) + (unsigned long)p;
+ }
+#endif
+
+ switch (array->a[VERT_ATTRIB_POS].type)
+ {
+ case GL_SHORT:
+ switch (array->a[VERT_ATTRIB_POS].size)
+ {
+ case 1: array_spu.self.VertexAttrib1svARB(0, (GLshort *)p); break;
+ case 2: array_spu.self.VertexAttrib2svARB(0, (GLshort *)p); break;
+ case 3: array_spu.self.VertexAttrib3svARB(0, (GLshort *)p); break;
+ case 4: array_spu.self.VertexAttrib4svARB(0, (GLshort *)p); break;
+ }
+ break;
+ case GL_INT:
+ iPtr = (GLint *) p;
+ switch (array->a[VERT_ATTRIB_POS].size)
+ {
+ case 1: array_spu.self.VertexAttrib1fARB(0, p[0]); break;
+ case 2: array_spu.self.VertexAttrib2fARB(0, p[0], p[1]); break;
+ case 3: array_spu.self.VertexAttrib3fARB(0, p[0], p[1], p[2]); break;
+ case 4: array_spu.self.VertexAttrib4fARB(0, p[0], p[1], p[2], p[3]); break;
+ }
+ break;
+ case GL_FLOAT:
+ switch (array->a[VERT_ATTRIB_POS].size)
+ {
+ case 1: array_spu.self.VertexAttrib1fvARB(0, (GLfloat *)p); break;
+ case 2: array_spu.self.VertexAttrib2fvARB(0, (GLfloat *)p); break;
+ case 3: array_spu.self.VertexAttrib3fvARB(0, (GLfloat *)p); break;
+ case 4: array_spu.self.VertexAttrib4fvARB(0, (GLfloat *)p); break;
+ }
+ break;
+ case GL_DOUBLE:
+ switch (array->a[VERT_ATTRIB_POS].size)
+ {
+ case 1: array_spu.self.VertexAttrib1dvARB(0, (GLdouble *)p); break;
+ case 2: array_spu.self.VertexAttrib2dvARB(0, (GLdouble *)p); break;
+ case 3: array_spu.self.VertexAttrib3dvARB(0, (GLdouble *)p); break;
+ case 4: array_spu.self.VertexAttrib4dvARB(0, (GLdouble *)p); break;
+ }
+ break;
+ default:
+ crWarning("Bad datatype for vertex attribute [0] array: 0x%x\n", array->a[0].type);
+ }
+ }
+ else if (array->v.enabled)
+ {
+ p = array->v.p + index * array->v.stride;
+
+#ifdef CR_ARB_vertex_buffer_object
+ if (array->v.buffer && array->v.buffer->data)
+ {
+ p = (unsigned char *)(array->v.buffer->data) + (unsigned long)p;
+ }
+#endif
+
+ switch (array->v.type)
+ {
+ case GL_SHORT:
+ switch (array->v.size)
+ {
+ case 2: array_spu.self.Vertex2sv((GLshort *)p); break;
+ case 3: array_spu.self.Vertex3sv((GLshort *)p); break;
+ case 4: array_spu.self.Vertex4sv((GLshort *)p); break;
+ }
+ break;
+ case GL_INT:
+ switch (array->v.size)
+ {
+ case 2: array_spu.self.Vertex2iv((GLint *)p); break;
+ case 3: array_spu.self.Vertex3iv((GLint *)p); break;
+ case 4: array_spu.self.Vertex4iv((GLint *)p); break;
+ }
+ break;
+ case GL_FLOAT:
+ switch (array->v.size)
+ {
+ case 2: array_spu.self.Vertex2fv((GLfloat *)p); break;
+ case 3: array_spu.self.Vertex3fv((GLfloat *)p); break;
+ case 4: array_spu.self.Vertex4fv((GLfloat *)p); break;
+ }
+ break;
+ case GL_DOUBLE:
+ switch (array->v.size)
+ {
+ case 2: array_spu.self.Vertex2dv((GLdouble *)p); break;
+ case 3: array_spu.self.Vertex3dv((GLdouble *)p); break;
+ case 4: array_spu.self.Vertex4dv((GLdouble *)p); break;
+ }
+ break;
+ default:
+ crWarning("Bad datatype for vertex array: 0x%x\n", array->v.type);
+ }
+ }
+}
+
+static void ARRAYSPU_APIENTRY arrayspu_DrawArrays(GLenum mode, GLint first, GLsizei count)
+{
+ int i;
+
+ if (count < 0)
+ {
+ crError("array_spu.self.DrawArrays passed negative count: %d", count);
+ }
+
+ if (mode > GL_POLYGON)
+ {
+ crError("array_spu.self.DrawArrays called with invalid mode: %d", mode);
+ }
+
+ array_spu.self.Begin(mode);
+ for (i=0; i<count; i++)
+ {
+ array_spu.self.ArrayElement(first++);
+ }
+ array_spu.self.End();
+}
+
+static void ARRAYSPU_APIENTRY arrayspu_DrawElements(GLenum mode, GLsizei count,
+ GLenum type, const GLvoid *indices)
+{
+ int i;
+ GLubyte *p = (GLubyte *)indices;
+#ifdef CR_ARB_vertex_buffer_object
+ CRBufferObject *elementsBuffer = crStateGetCurrent()->bufferobject.elementsBuffer;
+#endif
+
+ if (count < 0)
+ {
+ crError("array_spu.self.DrawElements passed negative count: %d", count);
+ }
+
+ if (mode > GL_POLYGON)
+ {
+ crError("array_spu.self.DrawElements called with invalid mode: %d", mode);
+ }
+
+ if (type != GL_UNSIGNED_BYTE && type != GL_UNSIGNED_SHORT && type != GL_UNSIGNED_INT)
+ {
+ crError("array_spu.self.DrawElements called with invalid type: %d", type);
+ }
+
+#ifdef CR_ARB_vertex_buffer_object
+ if (elementsBuffer && elementsBuffer->data)
+ {
+ p = (unsigned char *)(elementsBuffer->data) + (unsigned long)p;
+ }
+#endif
+ //crDebug("arrayspu_DrawElements mode:0x%x, count:%d, type:0x%x", mode, count, type);
+
+
+ array_spu.self.Begin(mode);
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ for (i=0; i<count; i++)
+ {
+ array_spu.self.ArrayElement((GLint) *p++);
+ }
+ break;
+ case GL_UNSIGNED_SHORT:
+ for (i=0; i<count; i++)
+ {
+ array_spu.self.ArrayElement((GLint) * (GLushort *) p);
+ p+=sizeof (GLushort);
+ }
+ break;
+ case GL_UNSIGNED_INT:
+ for (i=0; i<count; i++)
+ {
+ array_spu.self.ArrayElement((GLint) * (GLuint *) p);
+ p+=sizeof (GLuint);
+ }
+ break;
+ default:
+ crError( "this can't happen: array_spu.self.DrawElements" );
+ break;
+ }
+ array_spu.self.End();
+}
+
+static void ARRAYSPU_APIENTRY arrayspu_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices)
+{
+ if (start>end)
+ {
+ crError("array_spu.self.arrayspu_DrawRangeElements start>end (%d>%d)", start, end);
+ }
+
+ arrayspu_DrawElements(mode, count, type, indices);
+}
+
+static void ARRAYSPU_APIENTRY arrayspu_ColorPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+ crStateColorPointer(size, type, stride, pointer);
+ array_spu.child.ColorPointer(size, type, stride, pointer);
+}
+
+static void ARRAYSPU_APIENTRY arrayspu_SecondaryColorPointerEXT( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+ crStateSecondaryColorPointerEXT(size, type, stride, pointer);
+ array_spu.child.SecondaryColorPointerEXT(size, type, stride, pointer);
+}
+
+static void ARRAYSPU_APIENTRY arrayspu_VertexPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+ crStateVertexPointer(size, type, stride, pointer);
+ array_spu.child.VertexPointer(size, type, stride, pointer);
+}
+
+static void ARRAYSPU_APIENTRY arrayspu_TexCoordPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+ crStateTexCoordPointer(size, type, stride, pointer);
+ array_spu.child.TexCoordPointer(size, type, stride, pointer);
+}
+
+static void ARRAYSPU_APIENTRY arrayspu_NormalPointer( GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+ crStateNormalPointer(type, stride, pointer);
+ array_spu.child.NormalPointer(type, stride, pointer);
+}
+
+static void ARRAYSPU_APIENTRY arrayspu_IndexPointer( GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+ crStateIndexPointer(type, stride, pointer);
+ array_spu.child.IndexPointer(type, stride, pointer);
+}
+
+static void ARRAYSPU_APIENTRY arrayspu_EdgeFlagPointer( GLsizei stride, const GLvoid *pointer )
+{
+ crStateEdgeFlagPointer(stride, pointer);
+ array_spu.child.EdgeFlagPointer(stride, pointer);
+}
+
+static void ARRAYSPU_APIENTRY arrayspu_VertexAttribPointerNV( GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid * pointer )
+{
+ crStateVertexAttribPointerNV(index, size, type, stride, pointer);
+ array_spu.child.VertexAttribPointerNV(index, size, type, stride, pointer);
+}
+
+static void ARRAYSPU_APIENTRY arrayspu_FogCoordPointerEXT( GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+ crStateFogCoordPointerEXT(type, stride, pointer);
+ array_spu.child.FogCoordPointerEXT(type, stride, pointer);
+}
+
+static void ARRAYSPU_APIENTRY arrayspu_GetPointerv( GLenum pname, GLvoid **params )
+{
+ crStateGetPointerv(pname, params);
+}
+
+static void ARRAYSPU_APIENTRY arrayspu_EnableClientState( GLenum array )
+{
+ crStateEnableClientState(array);
+ array_spu.child.EnableClientState(array);
+}
+
+static void ARRAYSPU_APIENTRY arrayspu_DisableClientState( GLenum array )
+{
+ crStateDisableClientState(array);
+ array_spu.child.DisableClientState(array);
+}
+
+static void ARRAYSPU_APIENTRY arrayspu_ClientActiveTextureARB( GLenum texture )
+{
+ crStateClientActiveTextureARB(texture);
+ array_spu.child.ClientActiveTextureARB(texture);
+}
+
+static void ARRAYSPU_APIENTRY arrayspu_MultiDrawArraysEXT(GLenum mode, GLint *first, GLsizei *count, GLsizei primcount)
+{
+ int i;
+
+ if (primcount < 0)
+ {
+ crError("array_spu.self.MultiDrawArraysEXT passed negative count: %d", primcount);
+ }
+
+ if (mode > GL_POLYGON)
+ {
+ crError("array_spu.self.MultiDrawArraysEXT called with invalid mode: %d", mode);
+ }
+
+ for (i = 0; i < primcount; i++)
+ {
+ array_spu.self.DrawArrays(mode, first[i], count[i]);
+ }
+}
+
+static void ARRAYSPU_APIENTRY arrayspu_MultiDrawElementsEXT(GLenum mode, GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount)
+{
+ int i;
+
+ if (primcount < 0)
+ {
+ crError("array_spu.self.MultiDrawElementsEXT passed negative count: %d", primcount);
+ }
+
+ if (mode > GL_POLYGON)
+ {
+ crError("array_spu.self.MultiDrawElementsEXT called with invalid mode: %d", mode);
+ }
+
+ if (type != GL_UNSIGNED_BYTE && type != GL_UNSIGNED_SHORT && type != GL_UNSIGNED_INT)
+ {
+ crError("array_spu.self.MultiDrawElementsEXT called with invalid type: %d", type);
+ }
+
+ for (i = 0; i < primcount; i++)
+ {
+ array_spu.self.DrawElements(mode, count[i], type, indices[i]);
+ }
+}
+
+/*
+ * We need to know when vertex program mode is enabled/disabled
+ * in order to handle vertex attribute arrays correctly.
+ */
+static void ARRAYSPU_APIENTRY arrayspu_Enable(GLenum cap)
+{
+ if (cap == GL_VERTEX_PROGRAM_NV) {
+ crStateGetCurrent()->program.vpEnabled = GL_TRUE;
+ }
+ array_spu.child.Enable(cap);
+}
+
+
+static void ARRAYSPU_APIENTRY arrayspu_Disable(GLenum cap)
+{
+ if (cap == GL_VERTEX_PROGRAM_NV) {
+ crStateGetCurrent()->program.vpEnabled = GL_FALSE;
+ }
+ array_spu.child.Disable(cap);
+}
+
+/** @todo it's a hack, as GLSL shouldn't blindly reuse this bit from nv_vertex_program*/
+static void ARRAYSPU_APIENTRY arrayspu_UseProgram(GLuint program)
+{
+ crStateGetCurrent()->program.vpEnabled = program>0;
+ array_spu.child.UseProgram(program);
+}
+
+static void ARRAYSPU_APIENTRY
+arrayspu_VertexAttribPointerARB(GLuint index, GLint size, GLenum type,
+ GLboolean normalized, GLsizei stride,
+ const GLvoid *pointer)
+{
+ crStateVertexAttribPointerARB(index, size, type, normalized, stride, pointer);
+ array_spu.child.VertexAttribPointerARB(index, size, type, normalized, stride, pointer);
+}
+
+
+static void ARRAYSPU_APIENTRY
+arrayspu_EnableVertexAttribArrayARB(GLuint index)
+{
+ crStateEnableVertexAttribArrayARB(index);
+}
+
+
+static void ARRAYSPU_APIENTRY
+arrayspu_DisableVertexAttribArrayARB(GLuint index)
+{
+ crStateDisableVertexAttribArrayARB(index);
+}
+
+
+/* We need to implement Push/PopClientAttrib here so that _our_ state
+ * tracker gets used. Also, pass the call onto the next SPU (in case
+ * it's the GL_CLIENT_PIXEL_STORE_BIT, etc).
+ */
+static void ARRAYSPU_APIENTRY
+arrayspu_PushClientAttrib( GLbitfield mask )
+{
+ crStatePushClientAttrib(mask);
+ array_spu.child.PushClientAttrib(mask);
+}
+
+
+static void ARRAYSPU_APIENTRY
+arrayspu_PopClientAttrib( void )
+{
+ crStatePopClientAttrib();
+ array_spu.child.PopClientAttrib();
+}
+
+
+static void ARRAYSPU_APIENTRY
+arrayspu_GenBuffersARB( GLsizei n, GLuint * buffers )
+{
+ array_spu.child.GenBuffersARB(n, buffers);
+}
+
+static void ARRAYSPU_APIENTRY
+arrayspu_DeleteBuffersARB( GLsizei n, const GLuint *buffers )
+{
+ crStateDeleteBuffersARB(n, buffers);
+ array_spu.child.DeleteBuffersARB(n, buffers);
+}
+
+static void ARRAYSPU_APIENTRY
+arrayspu_BindBufferARB( GLenum target, GLuint buffer )
+{
+ crStateBindBufferARB(target, buffer);
+ array_spu.child.BindBufferARB(target, buffer);
+}
+
+static GLboolean ARRAYSPU_APIENTRY
+arrayspu_IsBufferARB (GLuint buffer)
+{
+ return array_spu.child.IsBufferARB(buffer);
+}
+
+static void ARRAYSPU_APIENTRY
+arrayspu_BufferDataARB( GLenum target, GLsizeiptrARB size, const GLvoid * data, GLenum usage )
+{
+ crStateBufferDataARB(target, size, data, usage);
+ array_spu.child.BufferDataARB(target, size, data, usage);
+}
+
+static void ARRAYSPU_APIENTRY
+arrayspu_BufferSubDataARB( GLenum target, GLintptrARB offset,
+ GLsizeiptrARB size, const GLvoid * data )
+{
+ crStateBufferSubDataARB(target, offset, size, data);
+ array_spu.child.BufferSubDataARB(target, offset, size, data);
+}
+
+static void ARRAYSPU_APIENTRY
+arrayspu_GetBufferSubDataARB(GLenum target, GLintptrARB offset, GLsizeiptrARB size, void * data)
+{
+ crStateGetBufferSubDataARB(target, offset, size, data);
+}
+
+static void * ARRAYSPU_APIENTRY
+arrayspu_MapBufferARB(GLenum target, GLenum access)
+{
+ return crStateMapBufferARB(target, access);
+}
+
+static GLboolean ARRAYSPU_APIENTRY
+arrayspu_UnmapBufferARB(GLenum target)
+{
+ crStateUnmapBufferARB(target);
+ return array_spu.child.UnmapBufferARB(target);
+}
+
+static void ARRAYSPU_APIENTRY
+arrayspu_GetBufferParameterivARB(GLenum target, GLenum pname, GLint *params)
+{
+ crStateGetBufferParameterivARB(target, pname, params);
+}
+
+static void ARRAYSPU_APIENTRY
+arrayspu_GetBufferPointervARB(GLenum target, GLenum pname, GLvoid **params)
+{
+ crStateGetBufferPointervARB(target, pname, params);
+}
+
+static void ARRAYSPU_APIENTRY
+arrayspu_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *p)
+{
+ crStateInterleavedArrays(format, stride, p);
+}
+
+static GLint ARRAYSPU_APIENTRY
+arrayspu_CreateContext( const char *dpyName, GLint visual, GLint shareCtx )
+{
+ GLint ctx, slot;
+
+#ifdef CHROMIUM_THREADSAFE
+ crLockMutex(&_ArrayMutex);
+#endif
+
+ ctx = array_spu.child.CreateContext(dpyName, visual, shareCtx);
+
+ /* find an empty context slot */
+ for (slot = 0; slot < array_spu.numContexts; slot++) {
+ if (!array_spu.context[slot].clientState) {
+ /* found empty slot */
+ break;
+ }
+ }
+ if (slot == array_spu.numContexts) {
+ array_spu.numContexts++;
+ }
+
+ array_spu.context[slot].clientState = crStateCreateContext(NULL, visual, NULL);
+ array_spu.context[slot].clientCtx = ctx;
+#ifdef CR_ARB_vertex_buffer_object
+ array_spu.context[slot].clientState->bufferobject.retainBufferData = GL_TRUE;
+#endif
+
+#ifdef CHROMIUM_THREADSAFE
+ crUnlockMutex(&_ArrayMutex);
+#endif
+
+ return ctx;
+}
+
+static void ARRAYSPU_APIENTRY
+arrayspu_MakeCurrent( GLint window, GLint nativeWindow, GLint ctx )
+{
+#ifdef CHROMIUM_THREADSAFE
+ crLockMutex(&_ArrayMutex);
+#endif
+ array_spu.child.MakeCurrent(window, nativeWindow, ctx);
+
+ if (ctx) {
+ int slot;
+
+ for (slot=0; slot<array_spu.numContexts; ++slot)
+ if (array_spu.context[slot].clientCtx == ctx) break;
+ CRASSERT(slot < array_spu.numContexts);
+
+ crStateMakeCurrent(array_spu.context[slot].clientState);
+ }
+ else
+ {
+ crStateMakeCurrent(NULL);
+ }
+
+#ifdef CHROMIUM_THREADSAFE
+ crUnlockMutex(&_ArrayMutex);
+#endif
+}
+
+static void ARRAYSPU_APIENTRY
+arrayspu_DestroyContext( GLint ctx )
+{
+#ifdef CHROMIUM_THREADSAFE
+ crLockMutex(&_ArrayMutex);
+#endif
+ array_spu.child.DestroyContext(ctx);
+
+ if (ctx) {
+ int slot;
+
+ for (slot=0; slot<array_spu.numContexts; ++slot)
+ if (array_spu.context[slot].clientCtx == ctx) break;
+ CRASSERT(slot < array_spu.numContexts);
+
+ crStateDestroyContext(array_spu.context[slot].clientState);
+
+ array_spu.context[slot].clientState = NULL;
+ array_spu.context[slot].clientCtx = 0;
+ }
+
+#ifdef CHROMIUM_THREADSAFE
+ crUnlockMutex(&_ArrayMutex);
+#endif
+}
+
+static void ARRAYSPU_APIENTRY
+arrayspu_VBoxAttachThread(void)
+{
+ crStateVBoxAttachThread();
+ array_spu.child.VBoxAttachThread();
+}
+
+static void ARRAYSPU_APIENTRY
+arrayspu_VBoxDetachThread(void)
+{
+ crStateVBoxDetachThread();
+ array_spu.child.VBoxDetachThread();
+}
+
+
+SPUNamedFunctionTable _cr_array_table[] = {
+ { "ArrayElement", (SPUGenericFunction) arrayspu_ArrayElement },
+ { "DrawArrays", (SPUGenericFunction) arrayspu_DrawArrays},
+ { "DrawElements", (SPUGenericFunction) arrayspu_DrawElements},
+ { "DrawRangeElements", (SPUGenericFunction) arrayspu_DrawRangeElements},
+ { "ColorPointer", (SPUGenericFunction) arrayspu_ColorPointer},
+ { "SecondaryColorPointerEXT", (SPUGenericFunction) arrayspu_SecondaryColorPointerEXT},
+ { "VertexPointer", (SPUGenericFunction) arrayspu_VertexPointer},
+ { "TexCoordPointer", (SPUGenericFunction) arrayspu_TexCoordPointer},
+ { "NormalPointer", (SPUGenericFunction) arrayspu_NormalPointer},
+ { "IndexPointer", (SPUGenericFunction) arrayspu_IndexPointer},
+ { "EdgeFlagPointer", (SPUGenericFunction) arrayspu_EdgeFlagPointer},
+ { "VertexAttribPointerNV", (SPUGenericFunction) arrayspu_VertexAttribPointerNV},
+ { "FogCoordPointerEXT", (SPUGenericFunction) arrayspu_FogCoordPointerEXT},
+ { "GetPointerv", (SPUGenericFunction) arrayspu_GetPointerv},
+ { "EnableClientState", (SPUGenericFunction) arrayspu_EnableClientState},
+ { "DisableClientState", (SPUGenericFunction) arrayspu_DisableClientState},
+ { "ClientActiveTextureARB", (SPUGenericFunction) arrayspu_ClientActiveTextureARB },
+ { "MultiDrawArraysEXT", (SPUGenericFunction) arrayspu_MultiDrawArraysEXT },
+ { "MultiDrawElementsEXT", (SPUGenericFunction) arrayspu_MultiDrawElementsEXT },
+ { "Enable", (SPUGenericFunction) arrayspu_Enable },
+ { "Disable", (SPUGenericFunction) arrayspu_Disable },
+ { "PushClientAttrib", (SPUGenericFunction) arrayspu_PushClientAttrib },
+ { "PopClientAttrib", (SPUGenericFunction) arrayspu_PopClientAttrib },
+ { "VertexAttribPointerARB", (SPUGenericFunction) arrayspu_VertexAttribPointerARB },
+ { "EnableVertexAttribArrayARB", (SPUGenericFunction) arrayspu_EnableVertexAttribArrayARB },
+ { "DisableVertexAttribArrayARB", (SPUGenericFunction) arrayspu_DisableVertexAttribArrayARB },
+ { "GenBuffersARB", (SPUGenericFunction) arrayspu_GenBuffersARB },
+ { "DeleteBuffersARB", (SPUGenericFunction) arrayspu_DeleteBuffersARB },
+ { "BindBufferARB", (SPUGenericFunction) arrayspu_BindBufferARB },
+ { "IsBufferARB", (SPUGenericFunction) arrayspu_IsBufferARB },
+ { "BufferDataARB", (SPUGenericFunction) arrayspu_BufferDataARB },
+ { "BufferSubDataARB", (SPUGenericFunction) arrayspu_BufferSubDataARB },
+ { "GetBufferSubDataARB", (SPUGenericFunction) arrayspu_GetBufferSubDataARB },
+ { "MapBufferARB", (SPUGenericFunction) arrayspu_MapBufferARB },
+ { "UnmapBufferARB", (SPUGenericFunction) arrayspu_UnmapBufferARB },
+ { "GetBufferParameterivARB", (SPUGenericFunction) arrayspu_GetBufferParameterivARB},
+ { "GetBufferPointervARB", (SPUGenericFunction) arrayspu_GetBufferPointervARB},
+ { "InterleavedArrays", (SPUGenericFunction) arrayspu_InterleavedArrays},
+ { "CreateContext", (SPUGenericFunction) arrayspu_CreateContext},
+ { "MakeCurrent", (SPUGenericFunction) arrayspu_MakeCurrent},
+ { "DestroyContext", (SPUGenericFunction) arrayspu_DestroyContext},
+ { "UseProgram", (SPUGenericFunction) arrayspu_UseProgram},
+ { "VBoxAttachThread", (SPUGenericFunction) arrayspu_VBoxAttachThread},
+ { "VBoxDetachThread", (SPUGenericFunction) arrayspu_VBoxDetachThread},
+ { NULL, NULL }
+};
diff --git a/src/VBox/Additions/common/crOpenGL/array/arrayspu.def b/src/VBox/Additions/common/crOpenGL/array/arrayspu.def
new file mode 100644
index 00000000..9edc7163
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/array/arrayspu.def
@@ -0,0 +1,6 @@
+; Copyright (c) 2001, Stanford University
+; All rights reserved.
+;
+; See the file LICENSE.txt for information on redistributing this software.
+EXPORTS
+SPULoad
diff --git a/src/VBox/Additions/common/crOpenGL/array/arrayspu.h b/src/VBox/Additions/common/crOpenGL/array/arrayspu.h
new file mode 100644
index 00000000..f31dea5c
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/array/arrayspu.h
@@ -0,0 +1,46 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved.
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#ifndef GA_INCLUDED_SRC_common_crOpenGL_array_arrayspu_h
+#define GA_INCLUDED_SRC_common_crOpenGL_array_arrayspu_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#ifdef WINDOWS
+#define ARRAYSPU_APIENTRY __stdcall
+#else
+#define ARRAYSPU_APIENTRY
+#endif
+
+#include "cr_spu.h"
+#include "cr_glstate.h"
+
+void arrayspuSetVBoxConfiguration( void );
+
+typedef struct context_info_t ContextInfo;
+
+struct context_info_t {
+ CRContext *clientState; /* used to store client-side GL state */
+ GLint clientCtx; /* client context ID */
+};
+
+typedef struct {
+ int id;
+ int has_child;
+ CRContext *defaultctx;
+ SPUDispatchTable self, child, super;
+ int numContexts;
+ ContextInfo context[CR_MAX_CONTEXTS];
+} ArraySPU;
+
+extern ArraySPU array_spu;
+
+#ifdef CHROMIUM_THREADSAFE
+extern CRmutex _ArrayMutex;
+#endif
+
+#endif /* !GA_INCLUDED_SRC_common_crOpenGL_array_arrayspu_h */
diff --git a/src/VBox/Additions/common/crOpenGL/array/arrayspu.rc b/src/VBox/Additions/common/crOpenGL/array/arrayspu.rc
new file mode 100644
index 00000000..894a6584
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/array/arrayspu.rc
@@ -0,0 +1,69 @@
+/* $Id: arrayspu.rc $ */
+/** @file
+ * VBoxOGLarrayspu - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2009-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_RC_FILE_VERSION
+ PRODUCTVERSION VBOX_RC_FILE_VERSION
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS VBOX_RC_FILE_FLAGS
+ FILEOS VBOX_RC_FILE_OS
+ FILETYPE VBOX_RC_TYPE_DRV
+ FILESUBTYPE VFT2_DRV_DISPLAY
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "VirtualBox crOpenGL ICD\0"
+ VALUE "InternalName", "VBoxOGLarrayspu\0"
+#ifdef VBOX_WDDM_WOW64
+ VALUE "OriginalFilename", "VBoxOGLarrayspu-x86.dll\0"
+#else
+ VALUE "OriginalFilename", "VBoxOGLarrayspu.dll\0"
+#endif
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileVersion", VBOX_RC_FILE_VERSION_STR
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "ProductName", VBOX_RC_PRODUCT_NAME_GA_STR
+ VALUE "ProductVersion", VBOX_RC_PRODUCT_VERSION_STR
+ VBOX_RC_MORE_STRINGS
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+1 RCDATA
+BEGIN
+// Machine dependent parameters
+ 17, // Height of vertical thumb
+ 17, // Width of horizontal thumb
+ 2, // Icon horiz compression factor
+ 2, // Icon vert compression factor
+ 1, // Cursor horz compression factor
+ 1, // Cursor vert compression factor
+ 0, // Kanji window height
+ 1, // cxBorder (thickness of vertical lines)
+ 1 // cyBorder (thickness of horizontal lines)
+END
diff --git a/src/VBox/Additions/common/crOpenGL/array/arrayspu_config.c b/src/VBox/Additions/common/crOpenGL/array/arrayspu_config.c
new file mode 100644
index 00000000..d2161739
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/array/arrayspu_config.c
@@ -0,0 +1,27 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "arrayspu.h"
+
+#include "cr_string.h"
+
+#include <stdio.h>
+
+static void __setDefaults( void )
+{
+}
+
+/* No SPU options yet.
+ */
+SPUOptions arraySPUOptions[] = {
+ { NULL, CR_BOOL, 0, NULL, NULL, NULL, NULL, NULL },
+};
+
+
+void arrayspuSetVBoxConfiguration( void )
+{
+ __setDefaults();
+}
diff --git a/src/VBox/Additions/common/crOpenGL/array/arrayspu_init.c b/src/VBox/Additions/common/crOpenGL/array/arrayspu_init.c
new file mode 100644
index 00000000..bd773f59
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/array/arrayspu_init.c
@@ -0,0 +1,86 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "cr_spu.h"
+#include "arrayspu.h"
+#include "cr_mem.h"
+#include <stdio.h>
+
+extern SPUNamedFunctionTable _cr_array_table[];
+
+extern SPUOptions arraySPUOptions[];
+
+static SPUFunctions array_functions = {
+ NULL, /* CHILD COPY */
+ NULL, /* DATA */
+ _cr_array_table /* THE ACTUAL FUNCTIONS */
+};
+
+static SPUFunctions *arraySPUInit( int id, SPU *child, SPU *self,
+ unsigned int context_id,
+ unsigned int num_contexts )
+{
+
+ (void) context_id;
+ (void) num_contexts;
+
+#ifdef CHROMIUM_THREADSAFE
+ crInitMutex(&_ArrayMutex);
+#endif
+
+ array_spu.id = id;
+ array_spu.has_child = 0;
+ if (child)
+ {
+ crSPUInitDispatchTable( &(array_spu.child) );
+ crSPUCopyDispatchTable( &(array_spu.child), &(child->dispatch_table) );
+ array_spu.has_child = 1;
+ }
+ crSPUInitDispatchTable( &(array_spu.super) );
+ crSPUCopyDispatchTable( &(array_spu.super), &(self->superSPU->dispatch_table) );
+ arrayspuSetVBoxConfiguration();
+
+ crStateInit();
+/** @todo seems default context ain't needed at all*/
+ array_spu.defaultctx = crStateCreateContext( NULL, 0, NULL );
+#ifdef CR_ARB_vertex_buffer_object
+ array_spu.defaultctx->bufferobject.retainBufferData = GL_TRUE;
+#endif
+ /* we call SetCurrent instead of MakeCurrent as the differencer
+ * isn't setup yet anyway */
+ crStateSetCurrent( array_spu.defaultctx );
+
+ array_spu.numContexts = 0;
+ crMemZero(array_spu.context, CR_MAX_CONTEXTS * sizeof(ContextInfo));
+
+ return &array_functions;
+}
+
+static void arraySPUSelfDispatch(SPUDispatchTable *self)
+{
+ crSPUInitDispatchTable( &(array_spu.self) );
+ crSPUCopyDispatchTable( &(array_spu.self), self );
+}
+
+static int arraySPUCleanup(void)
+{
+ return 1;
+}
+
+int SPULoad( char **name, char **super, SPUInitFuncPtr *init,
+ SPUSelfDispatchFuncPtr *self, SPUCleanupFuncPtr *cleanup,
+ SPUOptionsPtr *options, int *flags )
+{
+ *name = "array";
+ *super = "passthrough";
+ *init = arraySPUInit;
+ *self = arraySPUSelfDispatch;
+ *cleanup = arraySPUCleanup;
+ *options = arraySPUOptions;
+ *flags = (SPU_NO_PACKER|SPU_NOT_TERMINAL|SPU_MAX_SERVERS_ZERO);
+
+ return 1;
+}
diff --git a/src/VBox/Additions/common/crOpenGL/context.c b/src/VBox/Additions/common/crOpenGL/context.c
new file mode 100644
index 00000000..29b93aa1
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/context.c
@@ -0,0 +1,1463 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+/**
+ * \mainpage OpenGL_stub
+ *
+ * \section OpenGL_stubIntroduction Introduction
+ *
+ * Chromium consists of all the top-level files in the cr
+ * directory. The OpenGL_stub module basically takes care of API dispatch,
+ * and OpenGL state management.
+ *
+ */
+
+/**
+ * This file manages OpenGL rendering contexts in the faker library.
+ * The big issue is switching between Chromium and native GL context
+ * management. This is where we support multiple client OpenGL
+ * windows. Typically, one window is handled by Chromium while any
+ * other windows are handled by the native OpenGL library.
+ */
+
+#include "chromium.h"
+#include "cr_error.h"
+#include "cr_spu.h"
+#include "cr_mem.h"
+#include "cr_string.h"
+#include "cr_environment.h"
+#include "stub.h"
+
+/**
+ * This function should be called from MakeCurrent(). It'll detect if
+ * we're in a multi-thread situation, and do the right thing for dispatch.
+ */
+#ifdef CHROMIUM_THREADSAFE
+ static void
+stubCheckMultithread( void )
+{
+ static unsigned long knownID;
+ static GLboolean firstCall = GL_TRUE;
+
+ if (stub.threadSafe)
+ return; /* nothing new, nothing to do */
+
+ if (firstCall) {
+ knownID = crThreadID();
+ firstCall = GL_FALSE;
+ }
+ else if (knownID != crThreadID()) {
+ /* going thread-safe now! */
+ stub.threadSafe = GL_TRUE;
+ crSPUCopyDispatchTable(&glim, &stubThreadsafeDispatch);
+ }
+}
+#endif
+
+
+/**
+ * Install the given dispatch table as the table used for all gl* calls.
+ */
+ static void
+stubSetDispatch( SPUDispatchTable *table )
+{
+ CRASSERT(table);
+
+#ifdef CHROMIUM_THREADSAFE
+ /* always set the per-thread dispatch pointer */
+ crSetTSD(&stub.dispatchTSD, (void *) table);
+ if (stub.threadSafe) {
+ /* Do nothing - the thread-safe dispatch functions will call GetTSD()
+ * to get a pointer to the dispatch table, and jump through it.
+ */
+ }
+ else
+#endif
+ {
+ /* Single thread mode - just install the caller's dispatch table */
+ /* This conditional is an optimization to try to avoid unnecessary
+ * copying. It seems to work with atlantis, multiwin, etc. but
+ * _could_ be a problem. (Brian)
+ */
+ if (glim.copy_of != table->copy_of)
+ crSPUCopyDispatchTable(&glim, table);
+ }
+}
+
+void stubForcedFlush(GLint con)
+{
+#if 0
+ GLint buffer;
+ stub.spu->dispatch_table.GetIntegerv(GL_DRAW_BUFFER, &buffer);
+ stub.spu->dispatch_table.DrawBuffer(GL_FRONT);
+ stub.spu->dispatch_table.Flush();
+ stub.spu->dispatch_table.DrawBuffer(buffer);
+#else
+ if (con)
+ {
+ stub.spu->dispatch_table.VBoxConFlush(con);
+ }
+ else
+ {
+ stub.spu->dispatch_table.Flush();
+ }
+#endif
+}
+
+void stubConChromiumParameteriCR(GLint con, GLenum param, GLint value)
+{
+// if (con)
+ stub.spu->dispatch_table.VBoxConChromiumParameteriCR(con, param, value);
+// else
+// crError("VBoxConChromiumParameteriCR called with null connection");
+}
+
+void stubConChromiumParametervCR(GLint con, GLenum target, GLenum type, GLsizei count, const GLvoid *values)
+{
+// if (con)
+ stub.spu->dispatch_table.VBoxConChromiumParametervCR(con, target, type, count, values);
+// else
+// crError("VBoxConChromiumParameteriCR called with null connection");
+}
+
+void stubConFlush(GLint con)
+{
+ if (con)
+ stub.spu->dispatch_table.VBoxConFlush(con);
+ else
+ crError("stubConFlush called with null connection");
+}
+
+static void stubWindowCleanupForContextsCB(unsigned long key, void *data1, void *data2)
+{
+ ContextInfo *context = (ContextInfo *) data1;
+ RT_NOREF(key);
+
+ CRASSERT(context);
+
+ if (context->currentDrawable == data2)
+ context->currentDrawable = NULL;
+}
+
+void stubDestroyWindow( GLint con, GLint window )
+{
+ WindowInfo *winInfo = (WindowInfo *)
+ crHashtableSearch(stub.windowTable, (unsigned int) window);
+ if (winInfo && winInfo->type == CHROMIUM && stub.spu)
+ {
+ crHashtableLock(stub.windowTable);
+
+ stub.spu->dispatch_table.VBoxWindowDestroy(con, winInfo->spuWindow );
+
+#ifdef WINDOWS
+ if (winInfo->hVisibleRegion != INVALID_HANDLE_VALUE)
+ {
+ DeleteObject(winInfo->hVisibleRegion);
+ }
+#elif defined(GLX)
+ if (winInfo->pVisibleRegions)
+ {
+ XFree(winInfo->pVisibleRegions);
+ }
+# ifdef CR_NEWWINTRACK
+ if (winInfo->syncDpy)
+ {
+ XCloseDisplay(winInfo->syncDpy);
+ }
+# endif
+#endif
+
+ stubForcedFlush(con);
+
+ crHashtableWalk(stub.contextTable, stubWindowCleanupForContextsCB, winInfo);
+
+ crHashtableDelete(stub.windowTable, window, crFree);
+
+ crHashtableUnlock(stub.windowTable);
+ }
+}
+
+/**
+ * Create a new _Chromium_ window, not GLX, WGL or CGL.
+ * Called by crWindowCreate() only.
+ */
+ GLint
+stubNewWindow( const char *dpyName, GLint visBits )
+{
+ WindowInfo *winInfo;
+ GLint spuWin, size[2];
+
+ spuWin = stub.spu->dispatch_table.WindowCreate( dpyName, visBits );
+ if (spuWin < 0) {
+ return -1;
+ }
+
+ winInfo = (WindowInfo *) crCalloc(sizeof(WindowInfo));
+ if (!winInfo) {
+ stub.spu->dispatch_table.WindowDestroy(spuWin);
+ return -1;
+ }
+
+ winInfo->type = CHROMIUM;
+
+ /* Ask the head SPU for the initial window size */
+ size[0] = size[1] = 0;
+ stub.spu->dispatch_table.GetChromiumParametervCR(GL_WINDOW_SIZE_CR, 0, GL_INT, 2, size);
+ if (size[0] == 0 && size[1] == 0) {
+ /* use some reasonable defaults */
+ size[0] = size[1] = 512;
+ }
+ winInfo->width = size[0];
+ winInfo->height = size[1];
+#ifdef VBOX_WITH_WDDM
+ if (stub.bRunningUnderWDDM)
+ {
+ crError("Should not be here: WindowCreate/Destroy & VBoxPackGetInjectID require connection id!");
+ winInfo->mapped = 0;
+ }
+ else
+#endif
+ {
+ winInfo->mapped = 1;
+ }
+
+ if (!dpyName)
+ dpyName = "";
+
+ crStrncpy(winInfo->dpyName, dpyName, MAX_DPY_NAME);
+ winInfo->dpyName[MAX_DPY_NAME-1] = 0;
+
+ /* Use spuWin as the hash table index and GLX/WGL handle */
+#ifdef WINDOWS
+ winInfo->drawable = (HDC) spuWin;
+ winInfo->hVisibleRegion = INVALID_HANDLE_VALUE;
+#elif defined(Darwin)
+ winInfo->drawable = (CGSWindowID) spuWin;
+#elif defined(GLX)
+ winInfo->drawable = (GLXDrawable) spuWin;
+ winInfo->pVisibleRegions = NULL;
+ winInfo->cVisibleRegions = 0;
+#endif
+#ifdef CR_NEWWINTRACK
+ winInfo->u32ClientID = stub.spu->dispatch_table.VBoxPackGetInjectID(0);
+#endif
+ winInfo->spuWindow = spuWin;
+
+ crHashtableAdd(stub.windowTable, (unsigned int) spuWin, winInfo);
+
+ return spuWin;
+}
+
+#ifdef GLX
+# if 0 /* unused */
+static XErrorHandler oldErrorHandler;
+static unsigned char lastXError = Success;
+
+static int
+errorHandler (Display *dpy, XErrorEvent *e)
+{
+ RT_NOREF(dpy);
+
+ lastXError = e->error_code;
+ return 0;
+}
+# endif /* unused */
+#endif
+
+GLboolean
+stubIsWindowVisible(WindowInfo *win)
+{
+#if defined(WINDOWS)
+# ifdef VBOX_WITH_WDDM
+ if (stub.bRunningUnderWDDM)
+ return win->mapped;
+# endif
+ return GL_TRUE;
+#elif defined(Darwin)
+ return GL_TRUE;
+#elif defined(GLX)
+ Display *dpy = stubGetWindowDisplay(win);
+ if (dpy)
+ {
+ XWindowAttributes attr;
+ XLOCK(dpy);
+ XGetWindowAttributes(dpy, win->drawable, &attr);
+ XUNLOCK(dpy);
+
+ if (attr.map_state == IsUnmapped)
+ {
+ return GL_FALSE;
+ }
+# if 1
+ return GL_TRUE;
+# else
+ if (attr.override_redirect)
+ {
+ return GL_TRUE;
+ }
+
+ if (!stub.bXExtensionsChecked)
+ {
+ stubCheckXExtensions(win);
+ }
+
+ if (!stub.bHaveXComposite)
+ {
+ return GL_TRUE;
+ }
+ else
+ {
+ Pixmap p;
+
+ crLockMutex(&stub.mutex);
+
+ XLOCK(dpy);
+ XSync(dpy, false);
+ oldErrorHandler = XSetErrorHandler(errorHandler);
+ /** @todo this will create new pixmap for window every call*/
+ p = XCompositeNameWindowPixmap(dpy, win->drawable);
+ XSync(dpy, false);
+ XSetErrorHandler(oldErrorHandler);
+ XUNLOCK(dpy);
+
+ switch (lastXError)
+ {
+ case Success:
+ XFreePixmap(dpy, p);
+ crUnlockMutex(&stub.mutex);
+ return GL_FALSE;
+ break;
+ case BadMatch:
+ /*Window isn't redirected*/
+ lastXError = Success;
+ break;
+ default:
+ crWarning("Unexpected XError %i", (int)lastXError);
+ lastXError = Success;
+ }
+
+ crUnlockMutex(&stub.mutex);
+
+ return GL_TRUE;
+ }
+# endif
+ }
+ else {
+ /* probably created by crWindowCreate() */
+ return win->mapped;
+ }
+#endif
+}
+
+
+/**
+ * Given a Windows HDC or GLX Drawable, return the corresponding
+ * WindowInfo structure. Create a new one if needed.
+ */
+WindowInfo *
+#ifdef WINDOWS
+ stubGetWindowInfo( HDC drawable )
+#elif defined(Darwin)
+ stubGetWindowInfo( CGSWindowID drawable )
+#elif defined(GLX)
+stubGetWindowInfo( Display *dpy, GLXDrawable drawable )
+#endif
+{
+#ifndef WINDOWS
+ WindowInfo *winInfo = (WindowInfo *) crHashtableSearch(stub.windowTable, (unsigned int) drawable);
+#else
+ WindowInfo *winInfo;
+ HWND hwnd;
+ hwnd = WindowFromDC(drawable);
+
+ if (!hwnd)
+ {
+ return NULL;
+ }
+
+ winInfo = (WindowInfo *) crHashtableSearch(stub.windowTable, (unsigned int) hwnd);
+#endif
+ if (!winInfo) {
+ winInfo = (WindowInfo *) crCalloc(sizeof(WindowInfo));
+ if (!winInfo)
+ return NULL;
+#ifdef GLX
+ crStrncpy(winInfo->dpyName, DisplayString(dpy), MAX_DPY_NAME);
+ winInfo->dpyName[MAX_DPY_NAME-1] = 0;
+ winInfo->dpy = dpy;
+ winInfo->pVisibleRegions = NULL;
+#elif defined(Darwin)
+ winInfo->connection = _CGSDefaultConnection(); // store our connection as default
+#elif defined(WINDOWS)
+ winInfo->hVisibleRegion = INVALID_HANDLE_VALUE;
+ winInfo->hWnd = hwnd;
+#endif
+ winInfo->drawable = drawable;
+ winInfo->type = UNDECIDED;
+ winInfo->spuWindow = -1;
+#ifdef VBOX_WITH_WDDM
+ if (stub.bRunningUnderWDDM)
+ winInfo->mapped = 0;
+ else
+#endif
+ {
+ winInfo->mapped = -1; /* don't know */
+ }
+ winInfo->pOwner = NULL;
+#ifdef CR_NEWWINTRACK
+ winInfo->u32ClientID = -1;
+#endif
+#ifndef WINDOWS
+ crHashtableAdd(stub.windowTable, (unsigned int) drawable, winInfo);
+#else
+ crHashtableAdd(stub.windowTable, (unsigned int) hwnd, winInfo);
+#endif
+ }
+#ifdef WINDOWS
+ else
+ {
+ winInfo->drawable = drawable;
+ }
+#endif
+ return winInfo;
+}
+
+static void stubWindowCheckOwnerCB(unsigned long key, void *data1, void *data2);
+
+static void
+stubContextFree( ContextInfo *context )
+{
+ crMemZero(context, sizeof(ContextInfo)); /* just to be safe */
+ crFree(context);
+}
+
+static void
+stubDestroyContextLocked( ContextInfo *context )
+{
+ unsigned long contextId = context->id;
+ if (context->type == NATIVE) {
+#ifdef WINDOWS
+ stub.wsInterface.wglDeleteContext( context->hglrc );
+#elif defined(Darwin)
+ stub.wsInterface.CGLDestroyContext( context->cglc );
+#elif defined(GLX)
+ stub.wsInterface.glXDestroyContext( context->dpy, context->glxContext );
+#endif
+ }
+ else if (context->type == CHROMIUM) {
+ /* Have pack SPU or tilesort SPU, etc. destroy the context */
+ CRASSERT(context->spuContext >= 0);
+ stub.spu->dispatch_table.DestroyContext( context->spuContext );
+ crHashtableWalk(stub.windowTable, stubWindowCheckOwnerCB, context);
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ if (context->spuConnection)
+ {
+ stub.spu->dispatch_table.VBoxConDestroy(context->spuConnection);
+ context->spuConnection = 0;
+ }
+#endif
+ }
+
+#ifdef GLX
+ crFreeHashtable(context->pGLXPixmapsHash, crFree);
+#endif
+
+ crHashtableDelete(stub.contextTable, contextId, NULL);
+}
+
+#ifdef CHROMIUM_THREADSAFE
+static DECLCALLBACK(void) stubContextDtor(void*pvContext)
+{
+ stubContextFree((ContextInfo*)pvContext);
+}
+#endif
+
+/**
+ * Allocate a new ContextInfo object, initialize it, put it into the
+ * context hash table. If type==CHROMIUM, call the head SPU's
+ * CreateContext() function too.
+ */
+ ContextInfo *
+stubNewContext(char *dpyName, GLint visBits, ContextType type, unsigned long shareCtx
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , struct VBOXUHGSMI *pHgsmi
+#endif
+ )
+{
+ GLint spuContext = -1, spuShareCtx = 0, spuConnection = 0;
+ ContextInfo *context;
+
+ if (shareCtx > 0) {
+ /* translate shareCtx to a SPU context ID */
+ context = (ContextInfo *)
+ crHashtableSearch(stub.contextTable, shareCtx);
+ if (context)
+ spuShareCtx = context->spuContext;
+ }
+
+ if (type == CHROMIUM) {
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ if (pHgsmi)
+ {
+ spuConnection = stub.spu->dispatch_table.VBoxConCreate(pHgsmi);
+ if (!spuConnection)
+ {
+ crWarning("VBoxConCreate failed");
+ return NULL;
+ }
+ }
+#endif
+ spuContext
+ = stub.spu->dispatch_table.VBoxCreateContext(spuConnection, dpyName, visBits, spuShareCtx);
+ if (spuContext < 0)
+ {
+ crWarning("VBoxCreateContext failed");
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ if (spuConnection)
+ stub.spu->dispatch_table.VBoxConDestroy(spuConnection);
+#endif
+ return NULL;
+ }
+ }
+
+ context = crCalloc(sizeof(ContextInfo));
+ if (!context) {
+ stub.spu->dispatch_table.DestroyContext(spuContext);
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ if (spuConnection)
+ stub.spu->dispatch_table.VBoxConDestroy(spuConnection);
+#endif
+ return NULL;
+ }
+
+ if (!dpyName)
+ dpyName = "";
+
+ context->id = stub.freeContextNumber++;
+ context->type = type;
+ context->spuContext = spuContext;
+ context->visBits = visBits;
+ context->currentDrawable = NULL;
+ crStrncpy(context->dpyName, dpyName, MAX_DPY_NAME);
+ context->dpyName[MAX_DPY_NAME-1] = 0;
+
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ context->spuConnection = spuConnection;
+ context->pHgsmi = pHgsmi;
+#endif
+
+#ifdef CHROMIUM_THREADSAFE
+ VBoxTlsRefInit(context, stubContextDtor);
+#endif
+
+#if defined(GLX) || defined(DARWIN)
+ context->share = (ContextInfo *)
+ crHashtableSearch(stub.contextTable, (unsigned long) shareCtx);
+#endif
+
+#ifdef GLX
+ context->pGLXPixmapsHash = crAllocHashtable();
+ context->damageQueryFailed = GL_FALSE;
+ context->damageEventsBase = 0;
+#endif
+
+ crHashtableAdd(stub.contextTable, context->id, (void *) context);
+
+ return context;
+}
+
+
+#ifdef Darwin
+
+#define SET_ATTR(l,i,a) ( (l)[(i)++] = (a) )
+#define SET_ATTR_V(l,i,a,v) ( SET_ATTR(l,i,a), SET_ATTR(l,i,v) )
+
+void stubSetPFA( ContextInfo *ctx, CGLPixelFormatAttribute *attribs, int size, GLint *num ) {
+ GLuint visual = ctx->visBits;
+ int i = 0;
+
+ CRASSERT(visual & CR_RGB_BIT);
+
+ SET_ATTR_V(attribs, i, kCGLPFAColorSize, 8);
+
+ if( visual & CR_DEPTH_BIT )
+ SET_ATTR_V(attribs, i, kCGLPFADepthSize, 16);
+
+ if( visual & CR_ACCUM_BIT )
+ SET_ATTR_V(attribs, i, kCGLPFAAccumSize, 1);
+
+ if( visual & CR_STENCIL_BIT )
+ SET_ATTR_V(attribs, i, kCGLPFAStencilSize, 1);
+
+ if( visual & CR_ALPHA_BIT )
+ SET_ATTR_V(attribs, i, kCGLPFAAlphaSize, 1);
+
+ if( visual & CR_DOUBLE_BIT )
+ SET_ATTR(attribs, i, kCGLPFADoubleBuffer);
+
+ if( visual & CR_STEREO_BIT )
+ SET_ATTR(attribs, i, kCGLPFAStereo);
+
+/* SET_ATTR_V(attribs, i, kCGLPFASampleBuffers, 1);
+ SET_ATTR_V(attribs, i, kCGLPFASamples, 0);
+ SET_ATTR_V(attribs, i, kCGLPFADisplayMask, 0); */
+ SET_ATTR(attribs, i, kCGLPFABackingStore);
+ //SET_ATTR(attribs, i, kCGLPFAWindow); // kCGLPFAWindow deprecated starting from OSX 10.7
+ SET_ATTR_V(attribs, i, kCGLPFADisplayMask, ctx->disp_mask);
+
+ SET_ATTR(attribs, i, 0);
+
+ *num = i;
+}
+
+#endif
+
+#ifndef GLX
+/**
+ * This creates a native GLX/WGL context.
+ */
+static GLboolean
+InstantiateNativeContext( WindowInfo *window, ContextInfo *context )
+{
+#ifdef WINDOWS
+ context->hglrc = stub.wsInterface.wglCreateContext( window->drawable );
+ return context->hglrc ? GL_TRUE : GL_FALSE;
+#elif defined(Darwin)
+ CGLContextObj shareCtx = NULL;
+ CGLPixelFormatObj pix;
+ long npix;
+
+ CGLPixelFormatAttribute attribs[16];
+ GLint ind = 0;
+
+ if( context->share ) {
+ if( context->cglc != context->share->cglc ) {
+ crWarning("CGLCreateContext() is trying to share a non-existant "
+ "CGL context. Setting share context to zero.");
+ shareCtx = 0;
+ }
+ else
+ shareCtx = context->cglc;
+ }
+
+ stubSetPFA( context, attribs, 16, &ind );
+
+ stub.wsInterface.CGLChoosePixelFormat( attribs, &pix, &npix );
+ stub.wsInterface.CGLCreateContext( pix, shareCtx, &context->cglc );
+ if( !context->cglc )
+ crError("InstantiateNativeContext: Couldn't Create the context!");
+
+ stub.wsInterface.CGLDestroyPixelFormat( pix );
+
+ if( context->parambits ) {
+ /* Set the delayed parameters */
+ if( context->parambits & VISBIT_SWAP_RECT )
+ stub.wsInterface.CGLSetParameter( context->cglc, kCGLCPSwapRectangle, context->swap_rect );
+
+ if( context->parambits & VISBIT_SWAP_INTERVAL )
+ stub.wsInterface.CGLSetParameter( context->cglc, kCGLCPSwapInterval, &(context->swap_interval) );
+
+ if( context->parambits & VISBIT_CLIENT_STORAGE )
+ stub.wsInterface.CGLSetParameter( context->cglc, kCGLCPClientStorage, (long*)&(context->client_storage) );
+
+ context->parambits = 0;
+ }
+
+ return context->cglc ? GL_TRUE : GL_FALSE;
+#elif defined(GLX)
+ GLXContext shareCtx = 0;
+
+ /* sort out context sharing here */
+ if (context->share) {
+ if (context->glxContext != context->share->glxContext) {
+ crWarning("glXCreateContext() is trying to share a non-existant "
+ "GLX context. Setting share context to zero.");
+ shareCtx = 0;
+ }
+ else {
+ shareCtx = context->glxContext;
+ }
+ }
+
+ context->glxContext = stub.wsInterface.glXCreateContext( window->dpy,
+ context->visual, shareCtx, context->direct );
+
+ return context->glxContext ? GL_TRUE : GL_FALSE;
+#endif
+}
+#endif /* !GLX */
+
+
+/**
+ * Utility functions to get window size and titlebar text.
+ */
+#ifdef WINDOWS
+
+void
+stubGetWindowGeometry(WindowInfo *window, int *x, int *y,
+ unsigned int *w, unsigned int *h )
+{
+ RECT rect;
+
+ if (!window->drawable || !window->hWnd) {
+ *w = *h = 0;
+ return;
+ }
+
+ if (window->hWnd!=WindowFromDC(window->drawable))
+ {
+ crWarning("Window(%i) DC is no longer valid", window->spuWindow);
+ return;
+ }
+
+ if (!GetClientRect(window->hWnd, &rect))
+ {
+ crWarning("GetClientRect failed for %p", window->hWnd);
+ *w = *h = 0;
+ return;
+ }
+ *w = rect.right - rect.left;
+ *h = rect.bottom - rect.top;
+
+ if (!ClientToScreen( window->hWnd, (LPPOINT) &rect ))
+ {
+ crWarning("ClientToScreen failed for %p", window->hWnd);
+ *w = *h = 0;
+ return;
+ }
+ *x = rect.left;
+ *y = rect.top;
+}
+
+static void
+GetWindowTitle( const WindowInfo *window, char *title )
+{
+ /* XXX - we don't handle recurseUp */
+ if (window->hWnd)
+ GetWindowText(window->hWnd, title, 100);
+ else
+ title[0] = 0;
+}
+
+static void
+GetCursorPosition(WindowInfo *window, int pos[2])
+{
+ RECT rect;
+ POINT point;
+ GLint size[2], x, y;
+ unsigned int NativeHeight, NativeWidth, ChromiumHeight, ChromiumWidth;
+ float WidthRatio, HeightRatio;
+ static int DebugFlag = 0;
+
+ // apparently the "window" parameter passed to this
+ // function contains the native window information
+ HWND NATIVEhwnd = window->hWnd;
+
+ if (NATIVEhwnd!=WindowFromDC(window->drawable))
+ {
+ crWarning("Window(%i) DC is no longer valid", window->spuWindow);
+ return;
+ }
+
+ // get the native window's height and width
+ stubGetWindowGeometry(window, &x, &y, &NativeWidth, &NativeHeight);
+
+ // get the spu window's height and width
+ stub.spu->dispatch_table.GetChromiumParametervCR(GL_WINDOW_SIZE_CR, window->spuWindow, GL_INT, 2, size);
+ ChromiumWidth = size[0];
+ ChromiumHeight = size[1];
+
+ // get the ratio of the size of the native window to the cr window
+ WidthRatio = (float)ChromiumWidth / (float)NativeWidth;
+ HeightRatio = (float)ChromiumHeight / (float)NativeHeight;
+
+ // output some debug information at the beginning
+ if(DebugFlag)
+ {
+ DebugFlag = 0;
+ crDebug("Native Window Handle = %d", NATIVEhwnd);
+ crDebug("Native Width = %i", NativeWidth);
+ crDebug("Native Height = %i", NativeHeight);
+ crDebug("Chromium Width = %i", ChromiumWidth);
+ crDebug("Chromium Height = %i", ChromiumHeight);
+ }
+
+ if (NATIVEhwnd)
+ {
+ GetClientRect( NATIVEhwnd, &rect );
+ GetCursorPos (&point);
+
+ // make sure these coordinates are relative to the native window,
+ // not the whole desktop
+ ScreenToClient(NATIVEhwnd, &point);
+
+ // calculate the new position of the virtual cursor
+ pos[0] = (int)(point.x * WidthRatio);
+ pos[1] = (int)((NativeHeight - point.y) * HeightRatio);
+ }
+ else
+ {
+ pos[0] = 0;
+ pos[1] = 0;
+ }
+}
+
+#elif defined(Darwin)
+
+extern OSStatus CGSGetScreenRectForWindow( CGSConnectionID cid, CGSWindowID wid, float *outRect );
+extern OSStatus CGSGetWindowBounds( CGSConnectionID cid, CGSWindowID wid, float *bounds );
+
+void
+stubGetWindowGeometry( const WindowInfo *window, int *x, int *y, unsigned int *w, unsigned int *h )
+{
+ float rect[4];
+
+ if( !window ||
+ !window->connection ||
+ !window->drawable ||
+ CGSGetWindowBounds( window->connection, window->drawable, rect ) != noErr )
+ {
+ *x = *y = 0;
+ *w = *h = 0;
+ } else {
+ *x = (int) rect[0];
+ *y = (int) rect[1];
+ *w = (int) rect[2];
+ *h = (int) rect[3];
+ }
+}
+
+
+static void
+GetWindowTitle( const WindowInfo *window, char *title )
+{
+ /* XXX \todo Darwin window Title */
+ title[0] = '\0';
+}
+
+
+static void
+GetCursorPosition( const WindowInfo *window, int pos[2] )
+{
+ Point mouse_pos;
+ float window_rect[4];
+
+ GetMouse( &mouse_pos );
+ CGSGetScreenRectForWindow( window->connection, window->drawable, window_rect );
+
+ pos[0] = mouse_pos.h - (int) window_rect[0];
+ pos[1] = (int) window_rect[3] - (mouse_pos.v - (int) window_rect[1]);
+
+ /*crDebug( "%i %i", pos[0], pos[1] );*/
+}
+
+#elif defined(GLX)
+
+void
+stubGetWindowGeometry(WindowInfo *window, int *x, int *y, unsigned int *w, unsigned int *h)
+{
+ Window root, child;
+ unsigned int border, depth;
+ Display *dpy;
+
+ dpy = stubGetWindowDisplay(window);
+
+ /// @todo Performing those checks is expensive operation, especially for simple apps with high FPS.
+ // Disabling those triples glxgears fps, thus using xevents instead of per frame polling is much more preferred.
+ /// @todo Check similar on windows guests, though doubtful as there're no XSync like calls on windows.
+ if (window && dpy)
+ {
+ XLOCK(dpy);
+ }
+
+ if (!window
+ || !dpy
+ || !window->drawable
+ || !XGetGeometry(dpy, window->drawable, &root, x, y, w, h, &border, &depth)
+ || !XTranslateCoordinates(dpy, window->drawable, root, 0, 0, x, y, &child))
+ {
+ crWarning("Failed to get windows geometry for %p, try xwininfo", window);
+ *x = *y = 0;
+ *w = *h = 0;
+ }
+
+ if (window && dpy)
+ {
+ XUNLOCK(dpy);
+ }
+}
+
+static char *
+GetWindowTitleHelper( Display *dpy, Window window, GLboolean recurseUp )
+{
+ while (1) {
+ char *name;
+ if (!XFetchName(dpy, window, &name))
+ return NULL;
+ if (name[0]) {
+ return name;
+ }
+ else if (recurseUp) {
+ /* This window has no name, try the parent */
+ Status stat;
+ Window root, parent, *children;
+ unsigned int numChildren;
+ stat = XQueryTree( dpy, window, &root, &parent,
+ &children, &numChildren );
+ if (!stat || window == root)
+ return NULL;
+ if (children)
+ XFree(children);
+ window = parent;
+ }
+ else {
+ XFree(name);
+ return NULL;
+ }
+ }
+}
+
+static void
+GetWindowTitle( const WindowInfo *window, char *title )
+{
+ char *t = GetWindowTitleHelper(window->dpy, window->drawable, GL_TRUE);
+ if (t) {
+ crStrcpy(title, t);
+ XFree(t);
+ }
+ else {
+ title[0] = 0;
+ }
+}
+
+
+/**
+ *Return current cursor position in local window coords.
+ */
+static void
+GetCursorPosition(WindowInfo *window, int pos[2] )
+{
+ int rootX, rootY;
+ Window root, child;
+ unsigned int mask;
+ int x, y;
+
+ XLOCK(window->dpy);
+
+ Bool q = XQueryPointer(window->dpy, window->drawable, &root, &child,
+ &rootX, &rootY, &pos[0], &pos[1], &mask);
+ if (q) {
+ unsigned int w, h;
+ stubGetWindowGeometry( window, &x, &y, &w, &h );
+ /* invert Y */
+ pos[1] = (int) h - pos[1] - 1;
+ }
+ else {
+ pos[0] = pos[1] = 0;
+ }
+
+ XUNLOCK(window->dpy);
+}
+
+#endif
+
+
+/**
+ * This function is called by MakeCurrent() and determines whether or
+ * not a new rendering context should be bound to Chromium or the native
+ * OpenGL.
+ * \return GL_FALSE if native OpenGL should be used, or GL_TRUE if Chromium
+ * should be used.
+ */
+static GLboolean
+stubCheckUseChromium( WindowInfo *window )
+{
+ int x, y;
+ unsigned int w, h;
+
+ /* If the provided window is CHROMIUM, we're clearly intended
+ * to create a CHROMIUM context.
+ */
+ if (window->type == CHROMIUM)
+ return GL_TRUE;
+
+ if (stub.ignoreFreeglutMenus) {
+ const char *glutMenuTitle = "freeglut menu";
+ char title[1000];
+ GetWindowTitle(window, title);
+ if (crStrcmp(title, glutMenuTitle) == 0) {
+ crDebug("GL faker: Ignoring freeglut menu window");
+ return GL_FALSE;
+ }
+ }
+
+ /* If the user's specified a window count for Chromium, see if
+ * this window satisfies that criterium.
+ */
+ stub.matchChromiumWindowCounter++;
+ if (stub.matchChromiumWindowCount > 0) {
+ if (stub.matchChromiumWindowCounter != stub.matchChromiumWindowCount) {
+ crDebug("Using native GL, app window doesn't meet match_window_count");
+ return GL_FALSE;
+ }
+ }
+
+ /* If the user's specified a window list to ignore, see if this
+ * window satisfies that criterium.
+ */
+ if (stub.matchChromiumWindowID) {
+ GLuint i;
+
+ for (i = 0; i <= stub.numIgnoreWindowID; i++) {
+ if (stub.matchChromiumWindowID[i] == stub.matchChromiumWindowCounter) {
+ crDebug("Ignore window ID %d, using native GL", stub.matchChromiumWindowID[i]);
+ return GL_FALSE;
+ }
+ }
+ }
+
+ /* If the user's specified a minimum window size for Chromium, see if
+ * this window satisfies that criterium.
+ */
+ if (stub.minChromiumWindowWidth > 0 &&
+ stub.minChromiumWindowHeight > 0) {
+ stubGetWindowGeometry( window, &x, &y, &w, &h );
+ if (w >= stub.minChromiumWindowWidth &&
+ h >= stub.minChromiumWindowHeight) {
+
+ /* Check for maximum sized window now too */
+ if (stub.maxChromiumWindowWidth &&
+ stub.maxChromiumWindowHeight) {
+ if (w < stub.maxChromiumWindowWidth &&
+ h < stub.maxChromiumWindowHeight)
+ return GL_TRUE;
+ else
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+ }
+ crDebug("Using native GL, app window doesn't meet minimum_window_size");
+ return GL_FALSE;
+ }
+ else if (stub.matchWindowTitle) {
+ /* If the user's specified a window title for Chromium, see if this
+ * window satisfies that criterium.
+ */
+ GLboolean wildcard = GL_FALSE;
+ char title[1000];
+ char *titlePattern;
+ int len;
+ /* check for leading '*' wildcard */
+ if (stub.matchWindowTitle[0] == '*') {
+ titlePattern = crStrdup( stub.matchWindowTitle + 1 );
+ wildcard = GL_TRUE;
+ }
+ else {
+ titlePattern = crStrdup( stub.matchWindowTitle );
+ }
+ /* check for trailing '*' wildcard */
+ len = crStrlen(titlePattern);
+ if (len > 0 && titlePattern[len - 1] == '*') {
+ titlePattern[len - 1] = '\0'; /* terminate here */
+ wildcard = GL_TRUE;
+ }
+
+ GetWindowTitle( window, title );
+ if (title[0]) {
+ if (wildcard) {
+ if (crStrstr(title, titlePattern)) {
+ crFree(titlePattern);
+ return GL_TRUE;
+ }
+ }
+ else if (crStrcmp(title, titlePattern) == 0) {
+ crFree(titlePattern);
+ return GL_TRUE;
+ }
+ }
+ crFree(titlePattern);
+ crDebug("Using native GL, app window title doesn't match match_window_title string (\"%s\" != \"%s\")", title, stub.matchWindowTitle);
+ return GL_FALSE;
+ }
+
+ /* Window title and size don't matter */
+ CRASSERT(stub.minChromiumWindowWidth == 0);
+ CRASSERT(stub.minChromiumWindowHeight == 0);
+ CRASSERT(stub.matchWindowTitle == NULL);
+
+ /* User hasn't specified a width/height or window title.
+ * We'll use chromium for this window (and context) if no other is.
+ */
+
+ return GL_TRUE; /* use Chromium! */
+}
+
+static void stubWindowCheckOwnerCB(unsigned long key, void *data1, void *data2)
+{
+ WindowInfo *pWindow = (WindowInfo *) data1;
+ ContextInfo *pCtx = (ContextInfo *) data2;
+
+ RT_NOREF(key);
+
+
+ if (pWindow->pOwner == pCtx)
+ {
+#ifdef WINDOWS
+ /* Note: can't use WindowFromDC(context->pOwnWindow->drawable) here
+ because GL context is already released from DC and actual guest window
+ could be destroyed.
+ */
+ stubDestroyWindow(CR_CTX_CON(pCtx), (GLint)pWindow->hWnd);
+#else
+ stubDestroyWindow(CR_CTX_CON(pCtx), (GLint)pWindow->drawable);
+#endif
+ }
+}
+
+GLboolean stubCtxCreate(ContextInfo *context)
+{
+ /*
+ * Create a Chromium context.
+ */
+#if defined(GLX) || defined(DARWIN)
+ GLint spuShareCtx = context->share ? context->share->spuContext : 0;
+#else
+ GLint spuShareCtx = 0;
+#endif
+ GLint spuConnection = 0;
+ CRASSERT(stub.spu);
+ CRASSERT(stub.spu->dispatch_table.CreateContext);
+ context->type = CHROMIUM;
+
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ if (context->pHgsmi)
+ {
+ spuConnection = stub.spu->dispatch_table.VBoxConCreate(context->pHgsmi);
+ if (!spuConnection)
+ {
+ crError("VBoxConCreate failed");
+ return GL_FALSE;
+ }
+ context->spuConnection = spuConnection;
+ }
+#endif
+
+ context->spuContext
+ = stub.spu->dispatch_table.VBoxCreateContext(spuConnection, context->dpyName,
+ context->visBits,
+ spuShareCtx);
+
+ return GL_TRUE;
+}
+
+GLboolean stubCtxCheckCreate(ContextInfo *context)
+{
+ if (context->type == UNDECIDED)
+ return stubCtxCreate(context);
+ return CHROMIUM == context->type;
+}
+
+
+GLboolean
+stubMakeCurrent( WindowInfo *window, ContextInfo *context )
+{
+ GLboolean retVal = GL_FALSE;
+
+ /*
+ * Get WindowInfo and ContextInfo pointers.
+ */
+
+ if (!context || !window) {
+ ContextInfo * currentContext = stubGetCurrentContext();
+ if (currentContext)
+ currentContext->currentDrawable = NULL;
+ if (context)
+ context->currentDrawable = NULL;
+ stubSetCurrentContext(NULL);
+ return GL_TRUE; /* OK */
+ }
+
+#ifdef CHROMIUM_THREADSAFE
+ stubCheckMultithread();
+#endif
+
+ if (context->type == UNDECIDED) {
+ /* Here's where we really create contexts */
+#ifdef CHROMIUM_THREADSAFE
+ crLockMutex(&stub.mutex);
+#endif
+
+ if (stubCheckUseChromium(window)) {
+ GLint spuConnection = 0;
+
+ if (!stubCtxCreate(context))
+ {
+ crWarning("stubCtxCreate failed");
+ return GL_FALSE;
+ }
+
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ spuConnection = context->spuConnection;
+#endif
+
+ if (window->spuWindow == -1)
+ {
+ /*crDebug("(1)stubMakeCurrent ctx=%p(%i) window=%p(%i)", context, context->spuContext, window, window->spuWindow);*/
+ window->spuWindow = stub.spu->dispatch_table.VBoxWindowCreate(spuConnection, window->dpyName, context->visBits );
+#ifdef CR_NEWWINTRACK
+ window->u32ClientID = stub.spu->dispatch_table.VBoxPackGetInjectID(spuConnection);
+#endif
+ }
+ }
+#ifndef GLX
+ else {
+ /*
+ * Create a native OpenGL context.
+ */
+ if (!InstantiateNativeContext(window, context))
+ {
+# ifdef CHROMIUM_THREADSAFE
+ crUnlockMutex(&stub.mutex);
+# endif
+ return 0; /* false */
+ }
+ context->type = NATIVE;
+ }
+#endif /* !GLX */
+
+#ifdef CHROMIUM_THREADSAFE
+ crUnlockMutex(&stub.mutex);
+#endif
+ }
+
+
+ if (context->type == NATIVE) {
+ /*
+ * Native OpenGL MakeCurrent().
+ */
+#ifdef WINDOWS
+ retVal = (GLboolean) stub.wsInterface.wglMakeCurrent( window->drawable, context->hglrc );
+#elif defined(Darwin)
+ // XXX \todo We need to differentiate between these two..
+ retVal = ( stub.wsInterface.CGLSetSurface(context->cglc, window->connection, window->drawable, window->surface) == noErr );
+ retVal = ( stub.wsInterface.CGLSetCurrentContext(context->cglc) == noErr );
+#elif defined(GLX)
+ retVal = (GLboolean) stub.wsInterface.glXMakeCurrent( window->dpy, window->drawable, context->glxContext );
+#endif
+ }
+ else {
+ /*
+ * SPU chain MakeCurrent().
+ */
+ CRASSERT(context->type == CHROMIUM);
+ CRASSERT(context->spuContext >= 0);
+
+ /*if (context->currentDrawable && context->currentDrawable != window)
+ crDebug("Rebinding context %p to a different window", context);*/
+
+ if (window->type == NATIVE) {
+ crWarning("Can't rebind a chromium context to a native window\n");
+ retVal = 0;
+ }
+ else {
+ if (window->spuWindow == -1)
+ {
+ /*crDebug("(2)stubMakeCurrent ctx=%p(%i) window=%p(%i)", context, context->spuContext, window, window->spuWindow);*/
+ window->spuWindow = stub.spu->dispatch_table.VBoxWindowCreate(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ context->spuConnection,
+#else
+ 0,
+#endif
+ window->dpyName, context->visBits );
+#ifdef CR_NEWWINTRACK
+ window->u32ClientID = stub.spu->dispatch_table.VBoxPackGetInjectID(
+# if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ context->spuConnection
+# else
+ 0
+# endif
+ );
+#endif
+ if (context->currentDrawable && context->currentDrawable->type==CHROMIUM
+ && context->currentDrawable->pOwner==context)
+ {
+#ifdef WINDOWS
+ if (context->currentDrawable->hWnd!=WindowFromDC(context->currentDrawable->drawable))
+ {
+ stubDestroyWindow(CR_CTX_CON(context), (GLint)context->currentDrawable->hWnd);
+ }
+#else
+ Window root;
+ int x, y;
+ unsigned int border, depth, w, h;
+
+ XLOCK(context->currentDrawable->dpy);
+ if (!XGetGeometry(context->currentDrawable->dpy, context->currentDrawable->drawable, &root, &x, &y, &w, &h, &border, &depth))
+ {
+ stubDestroyWindow(CR_CTX_CON(context), (GLint)context->currentDrawable->drawable);
+ }
+ XUNLOCK(context->currentDrawable->dpy);
+#endif
+
+ }
+ }
+
+ if (window->spuWindow != (GLint)window->drawable)
+ stub.spu->dispatch_table.MakeCurrent( window->spuWindow, (GLint) window->drawable, context->spuContext );
+ else
+ stub.spu->dispatch_table.MakeCurrent( window->spuWindow, 0, /* native window handle */ context->spuContext );
+
+ retVal = 1;
+ }
+ }
+
+ window->type = context->type;
+ window->pOwner = context;
+ context->currentDrawable = window;
+ stubSetCurrentContext(context);
+
+ if (retVal) {
+ /* Now, if we've transitions from Chromium to native rendering, or
+ * vice versa, we have to change all the OpenGL entrypoint pointers.
+ */
+ if (context->type == NATIVE) {
+ /* Switch to native API */
+ /*printf(" Switching to native API\n");*/
+ stubSetDispatch(&stub.nativeDispatch);
+ }
+ else if (context->type == CHROMIUM) {
+ /* Switch to stub (SPU) API */
+ /*printf(" Switching to spu API\n");*/
+ stubSetDispatch(&stub.spuDispatch);
+ }
+ else {
+ /* no API switch needed */
+ }
+ }
+
+ if (!window->width && window->type == CHROMIUM) {
+ /* One time window setup */
+ int x, y;
+ unsigned int winW, winH;
+
+ stubGetWindowGeometry( window, &x, &y, &winW, &winH );
+
+ /* If we're not using GLX/WGL (no app window) we'll always get
+ * a width and height of zero here. In that case, skip the viewport
+ * call since we're probably using a tilesort SPU with fake_window_dims
+ * which the tilesort SPU will use for the viewport.
+ */
+ window->width = winW;
+ window->height = winH;
+#if defined(WINDOWS) && defined(VBOX_WITH_WDDM)
+ if (stubIsWindowVisible(window))
+#endif
+ {
+ if (stub.trackWindowSize)
+ stub.spuDispatch.WindowSize( window->spuWindow, winW, winH );
+ if (stub.trackWindowPos)
+ stub.spuDispatch.WindowPosition(window->spuWindow, x, y);
+ if (winW > 0 && winH > 0)
+ stub.spu->dispatch_table.Viewport( 0, 0, winW, winH );
+ }
+#ifdef VBOX_WITH_WDDM
+ if (stub.trackWindowVisibleRgn)
+ stub.spu->dispatch_table.WindowVisibleRegion(window->spuWindow, 0, NULL);
+#endif
+ }
+
+ /* Update window mapping state.
+ * Basically, this lets us hide render SPU windows which correspond
+ * to unmapped application windows. Without this, "pertly" (for example)
+ * opens *lots* of temporary windows which otherwise clutter the screen.
+ */
+ if (stub.trackWindowVisibility && window->type == CHROMIUM && window->drawable) {
+ const int mapped = stubIsWindowVisible(window);
+ if (mapped != window->mapped) {
+ crDebug("Dispatched: WindowShow(%i, %i)", window->spuWindow, mapped);
+ stub.spu->dispatch_table.WindowShow(window->spuWindow, mapped);
+ window->mapped = mapped;
+ }
+ }
+
+ return retVal;
+}
+
+void
+stubDestroyContext( unsigned long contextId )
+{
+ ContextInfo *context;
+
+ if (!stub.contextTable) {
+ return;
+ }
+
+ /* the lock order is windowTable->contextTable (see wglMakeCurrent_prox, glXMakeCurrent)
+ * this is why we need to take a windowTable lock since we will later do stub.windowTable access & locking */
+ crHashtableLock(stub.windowTable);
+ crHashtableLock(stub.contextTable);
+
+ context = (ContextInfo *) crHashtableSearch(stub.contextTable, contextId);
+ if (context)
+ stubDestroyContextLocked(context);
+ else
+ crError("No context.");
+
+#ifdef CHROMIUM_THREADSAFE
+ if (stubGetCurrentContext() == context) {
+ stubSetCurrentContext(NULL);
+ }
+
+ VBoxTlsRefMarkDestroy(context);
+ VBoxTlsRefRelease(context);
+#else
+ if (stubGetCurrentContext() == context) {
+ stubSetCurrentContext(NULL);
+ }
+ stubContextFree(context);
+#endif
+ crHashtableUnlock(stub.contextTable);
+ crHashtableUnlock(stub.windowTable);
+}
+
+void
+stubSwapBuffers(WindowInfo *window, GLint flags)
+{
+ if (!window)
+ return;
+
+ /* Determine if this window is being rendered natively or through
+ * Chromium.
+ */
+
+ if (window->type == NATIVE) {
+ /*printf("*** Swapping native window %d\n", (int) drawable);*/
+#ifdef WINDOWS
+ (void) stub.wsInterface.wglSwapBuffers( window->drawable );
+#elif defined(Darwin)
+ /* ...is this ok? */
+/* stub.wsInterface.CGLFlushDrawable( context->cglc ); */
+ crDebug("stubSwapBuffers: unable to swap (no context!)");
+#elif defined(GLX)
+ stub.wsInterface.glXSwapBuffers( window->dpy, window->drawable );
+#endif
+ }
+ else if (window->type == CHROMIUM) {
+ /* Let the SPU do the buffer swap */
+ /*printf("*** Swapping chromium window %d\n", (int) drawable);*/
+ if (stub.appDrawCursor) {
+ int pos[2];
+ GetCursorPosition(window, pos);
+ stub.spu->dispatch_table.ChromiumParametervCR(GL_CURSOR_POSITION_CR, GL_INT, 2, pos);
+ }
+ stub.spu->dispatch_table.SwapBuffers( window->spuWindow, flags );
+ }
+ else {
+ crDebug("Calling SwapBuffers on a window we haven't seen before (no-op).");
+ }
+}
diff --git a/src/VBox/Additions/common/crOpenGL/cr_gl.py b/src/VBox/Additions/common/crOpenGL/cr_gl.py
new file mode 100755
index 00000000..12e332ad
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/cr_gl.py
@@ -0,0 +1,65 @@
+from __future__ import print_function
+print("""
+/** @file
+ * VBox OpenGL chromium functions header
+ */
+
+/*
+ * Copyright (C) 2008-2016 """ """Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+""")
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+import sys
+
+import apiutil
+
+apiutil.CopyrightC()
+
+print("""
+/* DO NOT EDIT - THIS FILE GENERATED BY THE cr_gl.py SCRIPT */
+#ifndef __CR_GL_H__
+#define __CR_GL_H__
+
+#include "chromium.h"
+#include "cr_string.h"
+#include "cr_version.h"
+#include "stub.h"
+
+#ifdef WINDOWS
+#pragma warning( disable: 4055 )
+#endif
+
+""")
+
+
+# Extern-like declarations
+keys = apiutil.GetAllFunctions(sys.argv[1]+"/APIspec.txt")
+for func_name in keys:
+ if "Chromium" == apiutil.Category(func_name):
+ continue
+ if "VBox" == apiutil.Category(func_name):
+ continue
+ if func_name == "BoundsInfoCR":
+ continue
+ if "GL_chromium" == apiutil.Category(func_name):
+ pass #continue
+
+ return_type = apiutil.ReturnType(func_name)
+ params = apiutil.Parameters(func_name)
+
+ print("extern %s cr_gl%s(%s);" % (return_type, func_name,
+ apiutil.MakeDeclarationString( params )))
+
+print("#endif /* __CR_GL_H__ */")
diff --git a/src/VBox/Additions/common/crOpenGL/defs.py b/src/VBox/Additions/common/crOpenGL/defs.py
new file mode 100755
index 00000000..c0703088
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/defs.py
@@ -0,0 +1,505 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+apiutil.CopyrightDef()
+
+# NOTE: if we need a LIBRARY statement, we would need to create a defs-x86.py to generate a .def file for VBoxOGL-x86 library
+#print "LIBRARY VBoxOGL"
+#print "DESCRIPTION \"\"" - warning LNK4017: DESCRIPTION statement not supported for the target platform; ignored
+print("EXPORTS")
+
+# XXX can't these values be automatically computed by analyzing parameters?
+
+stack_sizes = {
+ 'Accum': 8,
+ 'AlphaFunc': 8,
+ 'AreTexturesResident': 12,
+ 'ArrayElement': 4,
+ 'Begin': 4,
+ 'BindTexture': 8,
+ 'Bitmap': 28,
+ 'BlendFunc': 8,
+ 'CallList': 4,
+ 'CallLists': 12,
+ 'Clear': 4,
+ 'ClearAccum': 16,
+ 'ClearColor': 16,
+ 'ClearDepth': 8,
+ 'ClearIndex': 4,
+ 'ClearStencil': 4,
+ 'ClipPlane': 8,
+ 'Color3b': 12,
+ 'Color3bv': 4,
+ 'Color3d': 24,
+ 'Color3dv': 4,
+ 'Color3f': 12,
+ 'Color3fv': 4,
+ 'Color3i': 12,
+ 'Color3iv': 4,
+ 'Color3s': 12,
+ 'Color3sv': 4,
+ 'Color3ub': 12,
+ 'Color3ubv': 4,
+ 'Color3ui': 12,
+ 'Color3uiv': 4,
+ 'Color3us': 12,
+ 'Color3usv': 4,
+ 'Color4b': 16,
+ 'Color4bv': 4,
+ 'Color4d': 32,
+ 'Color4dv': 4,
+ 'Color4f': 16,
+ 'Color4fv': 4,
+ 'Color4i': 16,
+ 'Color4iv': 4,
+ 'Color4s': 16,
+ 'Color4sv': 4,
+ 'Color4ub': 16,
+ 'Color4ubv': 4,
+ 'Color4ui': 16,
+ 'Color4uiv': 4,
+ 'Color4us': 16,
+ 'Color4usv': 4,
+ 'ColorMask': 16,
+ 'ColorMaterial': 8,
+ 'ColorPointer': 16,
+ 'CopyPixels': 20,
+ 'CopyTexImage1D': 28,
+ 'CopyTexImage2D': 32,
+ 'CopyTexSubImage1D': 24,
+ 'CopyTexSubImage2D': 32,
+ 'CullFace': 4,
+ 'DebugEntry': 8,
+ 'DeleteLists': 8,
+ 'DeleteTextures': 8,
+ 'DepthFunc': 4,
+ 'DepthMask': 4,
+ 'DepthRange': 16,
+ 'Disable': 4,
+ 'DisableClientState': 4,
+ 'DrawArrays': 12,
+ 'DrawBuffer': 4,
+ 'DrawElements': 16,
+ 'DrawPixels': 20,
+ 'EdgeFlag': 4,
+ 'EdgeFlagPointer': 8,
+ 'EdgeFlagv': 4,
+ 'Enable': 4,
+ 'EnableClientState': 4,
+ 'End': 0,
+ 'EndList': 0,
+ 'EvalCoord1d': 8,
+ 'EvalCoord1dv': 4,
+ 'EvalCoord1f': 4,
+ 'EvalCoord1fv': 4,
+ 'EvalCoord2d': 16,
+ 'EvalCoord2dv': 4,
+ 'EvalCoord2f': 8,
+ 'EvalCoord2fv': 4,
+ 'EvalMesh1': 12,
+ 'EvalMesh2': 20,
+ 'EvalPoint1': 4,
+ 'EvalPoint2': 8,
+ 'FeedbackBuffer': 12,
+ 'Finish': 0,
+ 'Flush': 0,
+ 'Fogf': 8,
+ 'Fogfv': 8,
+ 'Fogi': 8,
+ 'Fogiv': 8,
+ 'FrontFace': 4,
+ 'Frustum': 48,
+ 'GenLists': 4,
+ 'GenTextures': 8,
+ 'GetBooleanv': 8,
+ 'GetClipPlane': 8,
+ 'GetDoublev': 8,
+ 'GetError': 0,
+ 'GetFloatv': 8,
+ 'GetIntegerv': 8,
+ 'GetLightfv': 12,
+ 'GetLightiv': 12,
+ 'GetMapdv': 12,
+ 'GetMapfv': 12,
+ 'GetMapiv': 12,
+ 'GetMaterialfv': 12,
+ 'GetMaterialiv': 12,
+ 'GetPixelMapfv': 8,
+ 'GetPixelMapuiv': 8,
+ 'GetPixelMapusv': 8,
+ 'GetPointerv': 8,
+ 'GetPolygonStipple': 4,
+ 'GetString': 4,
+ 'GetTexEnvfv': 12,
+ 'GetTexEnviv': 12,
+ 'GetTexGendv': 12,
+ 'GetTexGenfv': 12,
+ 'GetTexGeniv': 12,
+ 'GetTexImage': 20,
+ 'GetTexLevelParameterfv': 16,
+ 'GetTexLevelParameteriv': 16,
+ 'GetTexParameterfv': 12,
+ 'GetTexParameteriv': 12,
+ 'Hint': 8,
+ 'IndexMask': 4,
+ 'IndexPointer': 12,
+ 'Indexd': 8,
+ 'Indexdv': 4,
+ 'Indexf': 4,
+ 'Indexfv': 4,
+ 'Indexi': 4,
+ 'Indexiv': 4,
+ 'Indexs': 4,
+ 'Indexsv': 4,
+ 'Indexub': 4,
+ 'Indexubv': 4,
+ 'InitNames': 0,
+ 'InterleavedArrays': 12,
+ 'IsEnabled': 4,
+ 'IsList': 4,
+ 'IsTexture': 4,
+ 'LightModelf': 8,
+ 'LightModelfv': 8,
+ 'LightModeli': 8,
+ 'LightModeliv': 8,
+ 'Lightf': 12,
+ 'Lightfv': 12,
+ 'Lighti': 12,
+ 'Lightiv': 12,
+ 'LineStipple': 8,
+ 'LineWidth': 4,
+ 'ListBase': 4,
+ 'LoadIdentity': 0,
+ 'LoadMatrixd': 4,
+ 'LoadMatrixf': 4,
+ 'LoadName': 4,
+ 'LogicOp': 4,
+ 'Map1d': 32,
+ 'Map1f': 24,
+ 'Map2d': 56,
+ 'Map2f': 40,
+ 'MapGrid1d': 20,
+ 'MapGrid1f': 12,
+ 'MapGrid2d': 40,
+ 'MapGrid2f': 24,
+ 'Materialf': 12,
+ 'Materialfv': 12,
+ 'Materiali': 12,
+ 'Materialiv': 12,
+ 'MatrixMode': 4,
+ 'MultMatrixd': 4,
+ 'MultMatrixf': 4,
+ 'NewList': 8,
+ 'Normal3b': 12,
+ 'Normal3bv': 4,
+ 'Normal3d': 24,
+ 'Normal3dv': 4,
+ 'Normal3f': 12,
+ 'Normal3fv': 4,
+ 'Normal3i': 12,
+ 'Normal3iv': 4,
+ 'Normal3s': 12,
+ 'Normal3sv': 4,
+ 'NormalPointer': 12,
+ 'Ortho': 48,
+ 'PassThrough': 4,
+ 'PixelMapfv': 12,
+ 'PixelMapuiv': 12,
+ 'PixelMapusv': 12,
+ 'PixelStoref': 8,
+ 'PixelStorei': 8,
+ 'PixelTransferf': 8,
+ 'PixelTransferi': 8,
+ 'PixelZoom': 8,
+ 'PointSize': 4,
+ 'PolygonMode': 8,
+ 'PolygonOffset': 8,
+ 'PolygonStipple': 4,
+ 'PopAttrib': 0,
+ 'PopClientAttrib': 0,
+ 'PopMatrix': 0,
+ 'PopName': 0,
+ 'PrioritizeTextures': 12,
+ 'PushAttrib': 4,
+ 'PushClientAttrib': 4,
+ 'PushMatrix': 0,
+ 'PushName': 4,
+ 'RasterPos2d': 16,
+ 'RasterPos2dv': 4,
+ 'RasterPos2f': 8,
+ 'RasterPos2fv': 4,
+ 'RasterPos2i': 8,
+ 'RasterPos2iv': 4,
+ 'RasterPos2s': 8,
+ 'RasterPos2sv': 4,
+ 'RasterPos3d': 24,
+ 'RasterPos3dv': 4,
+ 'RasterPos3f': 12,
+ 'RasterPos3fv': 4,
+ 'RasterPos3i': 12,
+ 'RasterPos3iv': 4,
+ 'RasterPos3s': 12,
+ 'RasterPos3sv': 4,
+ 'RasterPos4d': 32,
+ 'RasterPos4dv': 4,
+ 'RasterPos4f': 16,
+ 'RasterPos4fv': 4,
+ 'RasterPos4i': 16,
+ 'RasterPos4iv': 4,
+ 'RasterPos4s': 16,
+ 'RasterPos4sv': 4,
+ 'ReadBuffer': 4,
+ 'ReadPixels': 28,
+ 'Rectd': 32,
+ 'Rectdv': 8,
+ 'Rectf': 16,
+ 'Rectfv': 8,
+ 'Recti': 16,
+ 'Rectiv': 8,
+ 'Rects': 16,
+ 'Rectsv': 8,
+ 'RenderMode': 4,
+ 'Rotated': 32,
+ 'Rotatef': 16,
+ 'Scaled': 24,
+ 'Scalef': 12,
+ 'Scissor': 16,
+ 'SelectBuffer': 8,
+ 'ShadeModel': 4,
+ 'StencilFunc': 12,
+ 'StencilMask': 4,
+ 'StencilOp': 12,
+ 'TexCoord1d': 8,
+ 'TexCoord1dv': 4,
+ 'TexCoord1f': 4,
+ 'TexCoord1fv': 4,
+ 'TexCoord1i': 4,
+ 'TexCoord1iv': 4,
+ 'TexCoord1s': 4,
+ 'TexCoord1sv': 4,
+ 'TexCoord2d': 16,
+ 'TexCoord2dv': 4,
+ 'TexCoord2f': 8,
+ 'TexCoord2fv': 4,
+ 'TexCoord2i': 8,
+ 'TexCoord2iv': 4,
+ 'TexCoord2s': 8,
+ 'TexCoord2sv': 4,
+ 'TexCoord3d': 24,
+ 'TexCoord3dv': 4,
+ 'TexCoord3f': 12,
+ 'TexCoord3fv': 4,
+ 'TexCoord3i': 12,
+ 'TexCoord3iv': 4,
+ 'TexCoord3s': 12,
+ 'TexCoord3sv': 4,
+ 'TexCoord4d': 32,
+ 'TexCoord4dv': 4,
+ 'TexCoord4f': 16,
+ 'TexCoord4fv': 4,
+ 'TexCoord4i': 16,
+ 'TexCoord4iv': 4,
+ 'TexCoord4s': 16,
+ 'TexCoord4sv': 4,
+ 'TexCoordPointer': 16,
+ 'TexEnvf': 12,
+ 'TexEnvfv': 12,
+ 'TexEnvi': 12,
+ 'TexEnviv': 12,
+ 'TexGend': 16,
+ 'TexGendv': 12,
+ 'TexGenf': 12,
+ 'TexGenfv': 12,
+ 'TexGeni': 12,
+ 'TexGeniv': 12,
+ 'TexImage1D': 32,
+ 'TexImage2D': 36,
+ 'TexImage3D': 36,
+ 'TexParameterf': 12,
+ 'TexParameterfv': 12,
+ 'TexParameteri': 12,
+ 'TexParameteriv': 12,
+ 'TexSubImage1D': 28,
+ 'TexSubImage2D': 36,
+ 'Translated': 24,
+ 'Translatef': 12,
+ 'Vertex2d': 16,
+ 'Vertex2dv': 4,
+ 'Vertex2f': 8,
+ 'Vertex2fv': 4,
+ 'Vertex2i': 8,
+ 'Vertex2iv': 4,
+ 'Vertex2s': 8,
+ 'Vertex2sv': 4,
+ 'Vertex3d': 24,
+ 'Vertex3dv': 4,
+ 'Vertex3f': 12,
+ 'Vertex3fv': 4,
+ 'Vertex3i': 12,
+ 'Vertex3iv': 4,
+ 'Vertex3s': 12,
+ 'Vertex3sv': 4,
+ 'Vertex4d': 32,
+ 'Vertex4dv': 4,
+ 'Vertex4f': 16,
+ 'Vertex4fv': 4,
+ 'Vertex4i': 16,
+ 'Vertex4iv': 4,
+ 'Vertex4s': 16,
+ 'Vertex4sv': 4,
+ 'VertexPointer': 16,
+ 'Viewport': 16,
+ 'wglChoosePixelFormat': 8,
+ 'wglCopyContext': 12,
+ 'wglCreateContext': 4,
+ 'wglCreateLayerContext': 8,
+ 'wglDeleteContext': 4,
+ 'wglDescribeLayerPlane': 20,
+ 'wglDescribePixelFormat': 16,
+ 'wglGetCurrentContext': 0,
+ 'wglGetCurrentDC': 0,
+ 'wglGetDefaultProcAddress': 4,
+ 'wglGetLayerPaletteEntries': 20,
+ 'wglGetPixelFormat': 4,
+ 'wglGetProcAddress': 4,
+ 'wglMakeCurrent': 8,
+ 'wglRealizeLayerPalette': 12,
+ 'wglSetLayerPaletteEntries': 20,
+ 'wglSetPixelFormat': 12,
+ 'wglShareLists': 8,
+ 'wglSwapBuffers': 4,
+ 'wglSwapLayerBuffers': 8,
+ 'wglSwapMultipleBuffers': 8,
+ 'wglUseFontBitmapsA': 16,
+ 'wglUseFontBitmapsW': 16,
+ 'wglUseFontOutlinesA': 32,
+ 'wglUseFontOutlinesW': 32,
+ 'wglChoosePixelFormatEXT' : 24,
+ 'wglGetPixelFormatAttribivEXT' : 24,
+ 'wglGetPixelFormatAttribfvEXT' : 24,
+ 'wglGetExtensionsStringEXT' : 4,
+ 'CopyContext' : 12,
+ 'CreateContext' : 4,
+ 'CreateLayerContext' : 8,
+ 'DeleteContext' : 4,
+ 'DescribeLayerPlane' : 20,
+ 'DescribePixelFormat' : 16,
+ 'GetLayerPaletteEntries' : 20,
+ 'GetProcAddress' : 4,
+ 'RealizeLayerPalette' : 12,
+ 'ReleaseContext' : 4,
+ 'SetContext' : 12,
+ 'SetLayerPaletteEntries' : 20,
+ 'SetPixelFormat' : 12,
+ 'ShareLists' : 8,
+ 'SwapBuffers' : 4,
+ 'SwapLayerBuffers' : 8,
+ 'ValidateVersion' : 4,
+}
+
+noexport_special = [
+ "BoundsInfoCR",
+ "CreateContext",
+ "DestroyContext",
+ "MakeCurrent",
+ "WindowCreate",
+ "WindowDestroy",
+ "WindowSize",
+ "WindowPosition",
+ "WindowVisibleRegion",
+ "WindowShow",
+ "SwapBuffers"
+]
+
+keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+for func_name in keys:
+ if func_name in noexport_special:
+ continue
+ try:
+ print("gl%s@%d = cr_gl%s" % (func_name,stack_sizes[func_name],func_name))
+ except KeyError:
+ pass
+
+for func_name in ( "wglChoosePixelFormat",
+ "wglCopyContext",
+ "wglCreateContext",
+ "wglCreateLayerContext",
+ "wglDeleteContext",
+ "wglDescribeLayerPlane",
+ "wglDescribePixelFormat",
+ "wglGetCurrentContext",
+ "wglGetCurrentDC",
+ "wglGetLayerPaletteEntries",
+ "wglGetPixelFormat",
+ "wglGetProcAddress",
+ "wglMakeCurrent",
+ "wglRealizeLayerPalette",
+ "wglSetLayerPaletteEntries",
+ "wglSetPixelFormat",
+ "wglShareLists",
+ "wglSwapBuffers",
+ "wglSwapLayerBuffers",
+ "wglSwapMultipleBuffers",
+ "wglUseFontBitmapsA",
+ "wglUseFontBitmapsW",
+ "wglUseFontOutlinesA",
+ "wglUseFontOutlinesW",
+ "wglChoosePixelFormatEXT",
+ "wglGetPixelFormatAttribivEXT",
+ "wglGetPixelFormatAttribfvEXT",
+ "wglGetExtensionsStringEXT"):
+ print("%s = %s_prox" % (func_name,func_name))
+
+"""
+for func_name in ( "CopyContext",
+ "CreateContext",
+ "CreateLayerContext",
+ "DeleteContext",
+ "DescribeLayerPlane",
+ "DescribePixelFormat",
+ "GetLayerPaletteEntries",
+ "GetProcAddress",
+ "RealizeLayerPalette",
+ "SetLayerPaletteEntries",
+ "ShareLists",
+ "SwapBuffers",
+ "SwapLayerBuffers"):
+ print "Drv%s@%d = wgl%s_prox" % (func_name,stack_sizes[func_name],func_name)
+"""
+
+print("""DrvCopyContext
+DrvCreateContext
+DrvCreateLayerContext
+DrvDeleteContext
+DrvDescribeLayerPlane
+DrvDescribePixelFormat
+DrvGetLayerPaletteEntries
+DrvGetProcAddress = wglGetProcAddress_prox
+DrvRealizeLayerPalette
+DrvSetLayerPaletteEntries
+DrvShareLists
+DrvSwapBuffers
+DrvSwapLayerBuffers
+DrvReleaseContext@4 = DrvReleaseContext
+DrvSetContext@12 = DrvSetContext
+DrvValidateVersion@4 = DrvValidateVersion
+DrvSetPixelFormat@8 = DrvSetPixelFormat""")
+
+print("""crCreateContext
+crMakeCurrent
+crSwapBuffers
+crGetProcAddress
+VBoxCreateContext
+VBoxCtxChromiumParameteriCR
+VBoxGetWindowId
+VBoxGetContextId
+VBoxFlushToHost""")
+#print "DllMain"
diff --git a/src/VBox/Additions/common/crOpenGL/defs64.py b/src/VBox/Additions/common/crOpenGL/defs64.py
new file mode 100755
index 00000000..58971b9b
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/defs64.py
@@ -0,0 +1,485 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+apiutil.CopyrightDef()
+
+#print "LIBRARY VBoxOGL"
+#print "DESCRIPTION \"\"" - warning LNK4017: DESCRIPTION statement not supported for the target platform; ignored
+print("EXPORTS")
+
+# XXX can't these values be automatically computed by analyzing parameters?
+
+exports_special = [
+ 'Accum',
+ 'AlphaFunc',
+ 'AreTexturesResident',
+ 'ArrayElement',
+ 'Begin',
+ 'BindTexture',
+ 'Bitmap',
+ 'BlendFunc',
+ 'CallList',
+ 'CallLists',
+ 'Clear',
+ 'ClearAccum',
+ 'ClearColor',
+ 'ClearDepth',
+ 'ClearIndex',
+ 'ClearStencil',
+ 'ClipPlane',
+ 'Color3b',
+ 'Color3bv',
+ 'Color3d',
+ 'Color3dv',
+ 'Color3f',
+ 'Color3fv',
+ 'Color3i',
+ 'Color3iv',
+ 'Color3s',
+ 'Color3sv',
+ 'Color3ub',
+ 'Color3ubv',
+ 'Color3ui',
+ 'Color3uiv',
+ 'Color3us',
+ 'Color3usv',
+ 'Color4b',
+ 'Color4bv',
+ 'Color4d',
+ 'Color4dv',
+ 'Color4f',
+ 'Color4fv',
+ 'Color4i',
+ 'Color4iv',
+ 'Color4s',
+ 'Color4sv',
+ 'Color4ub',
+ 'Color4ubv',
+ 'Color4ui',
+ 'Color4uiv',
+ 'Color4us',
+ 'Color4usv',
+ 'ColorMask',
+ 'ColorMaterial',
+ 'ColorPointer',
+ 'CopyPixels',
+ 'CopyTexImage1D',
+ 'CopyTexImage2D',
+ 'CopyTexSubImage1D',
+ 'CopyTexSubImage2D',
+ 'CullFace',
+ 'DebugEntry',
+ 'DeleteLists',
+ 'DeleteTextures',
+ 'DepthFunc',
+ 'DepthMask',
+ 'DepthRange',
+ 'Disable',
+ 'DisableClientState',
+ 'DrawArrays',
+ 'DrawBuffer',
+ 'DrawElements',
+ 'DrawPixels',
+ 'EdgeFlag',
+ 'EdgeFlagPointer',
+ 'EdgeFlagv',
+ 'Enable',
+ 'EnableClientState',
+ 'End',
+ 'EndList',
+ 'EvalCoord1d',
+ 'EvalCoord1dv',
+ 'EvalCoord1f',
+ 'EvalCoord1fv',
+ 'EvalCoord2d',
+ 'EvalCoord2dv',
+ 'EvalCoord2f',
+ 'EvalCoord2fv',
+ 'EvalMesh1',
+ 'EvalMesh2',
+ 'EvalPoint1',
+ 'EvalPoint2',
+ 'FeedbackBuffer',
+ 'Finish',
+ 'Flush',
+ 'Fogf',
+ 'Fogfv',
+ 'Fogi',
+ 'Fogiv',
+ 'FrontFace',
+ 'Frustum',
+ 'GenLists',
+ 'GenTextures',
+ 'GetBooleanv',
+ 'GetClipPlane',
+ 'GetDoublev',
+ 'GetError',
+ 'GetFloatv',
+ 'GetIntegerv',
+ 'GetLightfv',
+ 'GetLightiv',
+ 'GetMapdv',
+ 'GetMapfv',
+ 'GetMapiv',
+ 'GetMaterialfv',
+ 'GetMaterialiv',
+ 'GetPixelMapfv',
+ 'GetPixelMapuiv',
+ 'GetPixelMapusv',
+ 'GetPointerv',
+ 'GetPolygonStipple',
+ 'GetString',
+ 'GetTexEnvfv',
+ 'GetTexEnviv',
+ 'GetTexGendv',
+ 'GetTexGenfv',
+ 'GetTexGeniv',
+ 'GetTexImage',
+ 'GetTexLevelParameterfv',
+ 'GetTexLevelParameteriv',
+ 'GetTexParameterfv',
+ 'GetTexParameteriv',
+ 'Hint',
+ 'IndexMask',
+ 'IndexPointer',
+ 'Indexd',
+ 'Indexdv',
+ 'Indexf',
+ 'Indexfv',
+ 'Indexi',
+ 'Indexiv',
+ 'Indexs',
+ 'Indexsv',
+ 'Indexub',
+ 'Indexubv',
+ 'InitNames',
+ 'InterleavedArrays',
+ 'IsEnabled',
+ 'IsList',
+ 'IsTexture',
+ 'LightModelf',
+ 'LightModelfv',
+ 'LightModeli',
+ 'LightModeliv',
+ 'Lightf',
+ 'Lightfv',
+ 'Lighti',
+ 'Lightiv',
+ 'LineStipple',
+ 'LineWidth',
+ 'ListBase',
+ 'LoadIdentity',
+ 'LoadMatrixd',
+ 'LoadMatrixf',
+ 'LoadName',
+ 'LogicOp',
+ 'Map1d',
+ 'Map1f',
+ 'Map2d',
+ 'Map2f',
+ 'MapGrid1d',
+ 'MapGrid1f',
+ 'MapGrid2d',
+ 'MapGrid2f',
+ 'Materialf',
+ 'Materialfv',
+ 'Materiali',
+ 'Materialiv',
+ 'MatrixMode',
+ 'MultMatrixd',
+ 'MultMatrixf',
+ 'NewList',
+ 'Normal3b',
+ 'Normal3bv',
+ 'Normal3d',
+ 'Normal3dv',
+ 'Normal3f',
+ 'Normal3fv',
+ 'Normal3i',
+ 'Normal3iv',
+ 'Normal3s',
+ 'Normal3sv',
+ 'NormalPointer',
+ 'Ortho',
+ 'PassThrough',
+ 'PixelMapfv',
+ 'PixelMapuiv',
+ 'PixelMapusv',
+ 'PixelStoref',
+ 'PixelStorei',
+ 'PixelTransferf',
+ 'PixelTransferi',
+ 'PixelZoom',
+ 'PointSize',
+ 'PolygonMode',
+ 'PolygonOffset',
+ 'PolygonStipple',
+ 'PopAttrib',
+ 'PopClientAttrib',
+ 'PopMatrix',
+ 'PopName',
+ 'PrioritizeTextures',
+ 'PushAttrib',
+ 'PushClientAttrib',
+ 'PushMatrix',
+ 'PushName',
+ 'RasterPos2d',
+ 'RasterPos2dv',
+ 'RasterPos2f',
+ 'RasterPos2fv',
+ 'RasterPos2i',
+ 'RasterPos2iv',
+ 'RasterPos2s',
+ 'RasterPos2sv',
+ 'RasterPos3d',
+ 'RasterPos3dv',
+ 'RasterPos3f',
+ 'RasterPos3fv',
+ 'RasterPos3i',
+ 'RasterPos3iv',
+ 'RasterPos3s',
+ 'RasterPos3sv',
+ 'RasterPos4d',
+ 'RasterPos4dv',
+ 'RasterPos4f',
+ 'RasterPos4fv',
+ 'RasterPos4i',
+ 'RasterPos4iv',
+ 'RasterPos4s',
+ 'RasterPos4sv',
+ 'ReadBuffer',
+ 'ReadPixels',
+ 'Rectd',
+ 'Rectdv',
+ 'Rectf',
+ 'Rectfv',
+ 'Recti',
+ 'Rectiv',
+ 'Rects',
+ 'Rectsv',
+ 'RenderMode',
+ 'Rotated',
+ 'Rotatef',
+ 'Scaled',
+ 'Scalef',
+ 'Scissor',
+ 'SelectBuffer',
+ 'ShadeModel',
+ 'StencilFunc',
+ 'StencilMask',
+ 'StencilOp',
+ 'TexCoord1d',
+ 'TexCoord1dv',
+ 'TexCoord1f',
+ 'TexCoord1fv',
+ 'TexCoord1i',
+ 'TexCoord1iv',
+ 'TexCoord1s',
+ 'TexCoord1sv',
+ 'TexCoord2d',
+ 'TexCoord2dv',
+ 'TexCoord2f',
+ 'TexCoord2fv',
+ 'TexCoord2i',
+ 'TexCoord2iv',
+ 'TexCoord2s',
+ 'TexCoord2sv',
+ 'TexCoord3d',
+ 'TexCoord3dv',
+ 'TexCoord3f',
+ 'TexCoord3fv',
+ 'TexCoord3i',
+ 'TexCoord3iv',
+ 'TexCoord3s',
+ 'TexCoord3sv',
+ 'TexCoord4d',
+ 'TexCoord4dv',
+ 'TexCoord4f',
+ 'TexCoord4fv',
+ 'TexCoord4i',
+ 'TexCoord4iv',
+ 'TexCoord4s',
+ 'TexCoord4sv',
+ 'TexCoordPointer',
+ 'TexEnvf',
+ 'TexEnvfv',
+ 'TexEnvi',
+ 'TexEnviv',
+ 'TexGend',
+ 'TexGendv',
+ 'TexGenf',
+ 'TexGenfv',
+ 'TexGeni',
+ 'TexGeniv',
+ 'TexImage1D',
+ 'TexImage2D',
+ 'TexImage3D',
+ 'TexParameterf',
+ 'TexParameterfv',
+ 'TexParameteri',
+ 'TexParameteriv',
+ 'TexSubImage1D',
+ 'TexSubImage2D',
+ 'Translated',
+ 'Translatef',
+ 'Vertex2d',
+ 'Vertex2dv',
+ 'Vertex2f',
+ 'Vertex2fv',
+ 'Vertex2i',
+ 'Vertex2iv',
+ 'Vertex2s',
+ 'Vertex2sv',
+ 'Vertex3d',
+ 'Vertex3dv',
+ 'Vertex3f',
+ 'Vertex3fv',
+ 'Vertex3i',
+ 'Vertex3iv',
+ 'Vertex3s',
+ 'Vertex3sv',
+ 'Vertex4d',
+ 'Vertex4dv',
+ 'Vertex4f',
+ 'Vertex4fv',
+ 'Vertex4i',
+ 'Vertex4iv',
+ 'Vertex4s',
+ 'Vertex4sv',
+ 'VertexPointer',
+ 'Viewport',
+ 'wglChoosePixelFormat',
+ 'wglCopyContext',
+ 'wglCreateContext',
+ 'wglCreateLayerContext',
+ 'wglDeleteContext',
+ 'wglDescribeLayerPlane',
+ 'wglDescribePixelFormat',
+ 'wglGetCurrentContext',
+ 'wglGetCurrentDC',
+ 'wglGetDefaultProcAddress',
+ 'wglGetLayerPaletteEntries',
+ 'wglGetPixelFormat',
+ 'wglGetProcAddress',
+ 'wglMakeCurrent',
+ 'wglRealizeLayerPalette',
+ 'wglSetLayerPaletteEntries',
+ 'wglSetPixelFormat',
+ 'wglShareLists',
+ 'wglSwapBuffers',
+ 'wglSwapLayerBuffers',
+ 'wglSwapMultipleBuffers',
+ 'wglUseFontBitmapsA',
+ 'wglUseFontBitmapsW',
+ 'wglUseFontOutlinesA',
+ 'wglUseFontOutlinesW',
+ 'wglChoosePixelFormatEXT',
+ 'wglGetPixelFormatAttribivEXT',
+ 'wglGetPixelFormatAttribfvEXT',
+ 'wglGetExtensionsStringEXT',
+ 'CopyContext',
+ 'CreateContext',
+ 'CreateLayerContext',
+ 'DeleteContext',
+ 'DescribeLayerPlane',
+ 'DescribePixelFormat',
+ 'GetLayerPaletteEntries',
+ 'GetProcAddress',
+ 'RealizeLayerPalette',
+ 'ReleaseContext',
+ 'SetContext',
+ 'SetLayerPaletteEntries',
+ 'SetPixelFormat',
+ 'ShareLists',
+ 'SwapBuffers',
+ 'SwapLayerBuffers',
+ 'ValidateVersion',
+]
+
+noexport_special = [
+ "BoundsInfoCR",
+ "CreateContext",
+ "DestroyContext",
+ "MakeCurrent",
+ "WindowCreate",
+ "WindowDestroy",
+ "WindowSize",
+ "WindowPosition",
+ "WindowVisibleRegion",
+ "WindowShow",
+ "SwapBuffers"
+]
+
+keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+for func_name in keys:
+ if func_name in noexport_special:
+ continue
+ if func_name in exports_special:
+ print("gl%s = cr_gl%s" % (func_name,func_name))
+
+for func_name in ( "wglChoosePixelFormat",
+ "wglCopyContext",
+ "wglCreateContext",
+ "wglCreateLayerContext",
+ "wglDeleteContext",
+ "wglDescribeLayerPlane",
+ "wglDescribePixelFormat",
+ "wglGetCurrentContext",
+ "wglGetCurrentDC",
+ "wglGetLayerPaletteEntries",
+ "wglGetPixelFormat",
+ "wglGetProcAddress",
+ "wglMakeCurrent",
+ "wglRealizeLayerPalette",
+ "wglSetLayerPaletteEntries",
+ "wglSetPixelFormat",
+ "wglShareLists",
+ "wglSwapBuffers",
+ "wglSwapLayerBuffers",
+ "wglSwapMultipleBuffers",
+ "wglUseFontBitmapsA",
+ "wglUseFontBitmapsW",
+ "wglUseFontOutlinesA",
+ "wglUseFontOutlinesW",
+ "wglChoosePixelFormatEXT",
+ "wglGetPixelFormatAttribivEXT",
+ "wglGetPixelFormatAttribfvEXT",
+ "wglGetExtensionsStringEXT"):
+ print("%s = %s_prox" % (func_name,func_name))
+
+print("""DrvCopyContext
+DrvCreateContext
+DrvCreateLayerContext
+DrvDeleteContext
+DrvDescribeLayerPlane
+DrvDescribePixelFormat
+DrvGetLayerPaletteEntries
+DrvGetProcAddress = wglGetProcAddress_prox
+DrvRealizeLayerPalette
+DrvSetLayerPaletteEntries
+DrvShareLists
+DrvSwapBuffers
+DrvSwapLayerBuffers
+DrvReleaseContext = DrvReleaseContext
+DrvSetContext = DrvSetContext
+DrvValidateVersion = DrvValidateVersion
+DrvSetPixelFormat = DrvSetPixelFormat""")
+
+print("""crCreateContext
+crMakeCurrent
+crSwapBuffers
+crGetProcAddress
+VBoxCreateContext
+VBoxCtxChromiumParameteriCR
+VBoxGetWindowId
+VBoxGetContextId
+VBoxFlushToHost""")
+#print "DllMain"
diff --git a/src/VBox/Additions/common/crOpenGL/dri_drv.c b/src/VBox/Additions/common/crOpenGL/dri_drv.c
new file mode 100644
index 00000000..de206624
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/dri_drv.c
@@ -0,0 +1,1012 @@
+/* $Id: dri_drv.c $ */
+
+/** @file
+ * VBox OpenGL DRI driver functions
+ */
+
+/*
+ * Copyright (C) 2009-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ * --------------------------------------------------------------------
+ *
+ * This file is based in part on the tdfx driver from X.Org/Mesa, with the
+ * following copyright notice:
+ *
+ * Copyright 2000 VA Linux Systems Inc., Fremont, California.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEMS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Original rewrite:
+ * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000
+ *
+ * Authors:
+ * Gareth Hughes <gareth@valinux.com>
+ */
+
+#include "cr_error.h"
+#include "cr_gl.h"
+#include "stub.h"
+#include "dri_drv.h"
+#include "DD_gl.h"
+
+/** @todo some of those are or'ed with GL_VERSIONS and ain't needed here*/
+#define need_GL_ARB_occlusion_query
+#define need_GL_ARB_point_parameters
+#define need_GL_NV_point_sprite
+#define need_GL_ARB_texture_compression
+#define need_GL_ARB_transpose_matrix
+#define need_GL_ARB_vertex_buffer_object
+#define need_GL_ARB_vertex_program
+#define need_GL_ARB_window_pos
+#define need_GL_EXT_blend_color
+#define need_GL_EXT_blend_minmax
+#define need_GL_EXT_blend_func_separate
+#define need_GL_EXT_fog_coord
+#define need_GL_EXT_multi_draw_arrays
+#define need_GL_EXT_secondary_color
+#define need_GL_EXT_texture_object
+#define need_GL_EXT_texture3D
+#define need_GL_VERSION_1_3
+#define need_GL_VERSION_1_4
+#define need_GL_VERSION_1_5
+
+#include "drivers/dri/common/extension_helper.h"
+
+/** @todo add more which are supported by chromium like GL_NV_vertex_program etc.*/
+static const struct dri_extension vbox_extensions[] = {
+ { "GL_ARB_depth_texture", NULL },
+ { "GL_ARB_fragment_program", NULL },
+ { "GL_ARB_multitexture", NULL },
+ { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions },
+ { "GL_ARB_point_parameters", GL_ARB_point_parameters_functions },
+ { "GL_NV_point_sprite", GL_NV_point_sprite_functions },
+ { "GL_ARB_shadow", NULL },
+ { "GL_ARB_shadow_ambient", NULL },
+ { "GL_ARB_texture_border_clamp", NULL },
+ { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions },
+ { "GL_ARB_texture_cube_map", NULL },
+ { "GL_ARB_texture_env_add", NULL },
+ { "GL_ARB_texture_env_combine", NULL },
+ { "GL_EXT_texture_env_combine", NULL },
+ { "GL_ARB_texture_env_crossbar", NULL },
+ { "GL_ARB_texture_env_dot3", NULL },
+ { "GL_EXT_texture_env_dot3", NULL },
+ { "GL_ARB_texture_mirrored_repeat", NULL },
+ { "GL_ARB_texture_non_power_of_two", NULL },
+ { "GL_ARB_transpose_matrix", GL_ARB_transpose_matrix_functions },
+ { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions },
+ { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions },
+ { "GL_ARB_window_pos", GL_ARB_window_pos_functions },
+ { "GL_EXT_blend_color", GL_EXT_blend_color_functions },
+ { "GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions },
+ { "GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions },
+ { "GL_EXT_blend_subtract", NULL },
+ { "GL_EXT_texture_env_add", NULL }, /** @todo that's an alias to GL_ARB version, remove it?*/
+ { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
+ { "GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions },
+ { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions },
+ { "GL_EXT_shadow_funcs", NULL },
+ { "GL_EXT_stencil_wrap", NULL },
+ { "GL_EXT_texture_cube_map", NULL }, /** @todo another alias*/
+ { "GL_EXT_texture_edge_clamp", NULL },
+ { "GL_EXT_texture_filter_anisotropic", NULL },
+ { "GL_EXT_texture_lod_bias", NULL },
+ { "GL_EXT_texture_object", GL_EXT_texture_object_functions },
+ { "GL_EXT_texture3D", GL_EXT_texture3D_functions },
+ { "GL_NV_texgen_reflection", NULL },
+ { "GL_ARB_texture_rectangle", NULL },
+ { "GL_SGIS_generate_mipmap", NULL },
+ { "GL_SGIS_texture_edge_clamp", NULL } /** @todo another alias*/
+};
+
+static void
+vboxdriInitExtensions(GLcontext * ctx)
+{
+ /** @todo have to check extensions supported by host here first */
+ driInitExtensions(ctx, vbox_extensions, GL_FALSE);
+}
+
+static GLvertexformat vboxdriTnlVtxFmt;
+
+
+/* This callback tells us that Mesa's internal state has changed. We probably
+ * don't need to handle this ourselves, so just pass it on to other parts of
+ * Mesa we may be using, as the swrast driver and others do */
+static void
+vboxDDUpdateState(GLcontext * ctx, GLuint new_state)
+{
+ _swrast_InvalidateState(ctx, new_state);
+ _swsetup_InvalidateState(ctx, new_state);
+ _vbo_InvalidateState(ctx, new_state);
+ _tnl_InvalidateState(ctx, new_state);
+}
+
+#if 0 /* See comment in vboxdriInitFuncs */
+static void
+vboxDDGetBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height)
+{
+ /*do something, note it's obsolete*/
+}
+
+static void
+vboxDDResizeBuffer( GLcontext *ctx, GLframebuffer *fb,
+ GLuint width, GLuint height)
+{
+ /*do something, note it's obsolete*/
+}
+
+static void
+vboxDDError(GLcontext *ctx)
+{
+ //__GLcontextRec::ErrorValue contains the error value.
+}
+#endif
+
+static void
+vboxDDDrawPixels(GLcontext *ctx,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLvoid *pixels)
+{
+}
+
+static void
+vboxDDReadPixels(GLcontext *ctx,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *unpack,
+ GLvoid *dest)
+{
+}
+
+static void
+vboxDDCopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
+ GLsizei width, GLsizei height,
+ GLint dstx, GLint dsty, GLenum type)
+{
+}
+
+static void
+vboxDDBitmap(GLcontext *ctx,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLubyte *bitmap)
+{
+}
+
+static void
+vboxDDTexImage1D(GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint border,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+}
+
+static void
+vboxDDTexImage2D(GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint border,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+}
+
+static void
+vboxDDTexImage3D(GLcontext *ctx, GLenum target, GLint level,
+ GLint internalFormat,
+ GLint width, GLint height, GLint depth, GLint border,
+ GLenum format, GLenum type, const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+}
+
+static void
+vboxDDTexSubImage1D(GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset, GLsizei width,
+ GLenum format, GLenum type,
+ const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+}
+
+static void
+vboxDDTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+}
+
+
+static void
+vboxDDTexSubImage3D(GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLint depth,
+ GLenum format, GLenum type,
+ const GLvoid *pixels,
+ const struct gl_pixelstore_attrib *packing,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+}
+
+
+static void
+vboxDDGetTexImage(GLcontext *ctx, GLenum target, GLint level,
+ GLenum format, GLenum type, GLvoid *pixels,
+ struct gl_texture_object *texObj,
+ struct gl_texture_image *texImage)
+{
+}
+
+static void
+vboxDDBindTexture(GLcontext *ctx, GLenum target,
+ struct gl_texture_object *tObj)
+{
+}
+
+static GLboolean
+vboxDDIsTextureResident(GLcontext *ctx, struct gl_texture_object *t)
+{
+}
+
+static void
+vboxDDPrioritizeTexture(GLcontext *ctx, struct gl_texture_object *t,
+ GLclampf priority)
+{
+}
+
+static void
+vboxDDBlendColor(GLcontext *ctx, const GLfloat color[4])
+{
+}
+
+static void
+vboxDDClearColor(GLcontext *ctx, const GLfloat color[4])
+{
+}
+
+static void
+vboxDDClearIndex(GLcontext *ctx, GLuint index)
+{
+}
+
+static void
+vboxDDClipPlane(GLcontext *ctx, GLenum plane, const GLfloat *equation)
+{
+}
+
+/** @todo Enable or disable server-side gl capabilities, not related to glEnable? */
+static void
+vboxDDEnable(GLcontext *ctx, GLenum cap, GLboolean state)
+{
+ if (state)
+ cr_glEnable(cap);
+ else
+ cr_glDisable(cap);
+}
+
+static void
+vboxDDRenderMode(GLcontext *ctx, GLenum mode)
+{
+ cr_glRenderMode(mode);
+}
+
+static void
+vboxDDTexParameter(GLcontext *ctx, GLenum target,
+ struct gl_texture_object *texObj,
+ GLenum pname, const GLfloat *params)
+{
+}
+
+/*Note, checking glGetError before and after those calls is the only way
+ *to return if we succeeded to get value or not, but it will add 2 sync calls and
+ *will reset glGetError value returned in case application calls it explicitly
+ */
+static GLboolean
+vboxDDGetBooleanv(GLcontext *ctx, GLenum pname, GLboolean *result)
+{
+ cr_glGetBooleanv(pname, result);
+ return GL_TRUE;
+}
+
+static GLboolean
+vboxDDGetDoublev(GLcontext *ctx, GLenum pname, GLdouble *result)
+{
+ cr_glGetDoublev(pname, result);
+ return GL_TRUE;
+}
+
+static GLboolean
+vboxDDGetFloatv(GLcontext *ctx, GLenum pname, GLfloat *result)
+{
+ cr_glGetFloatv(pname, result);
+ return GL_TRUE;
+}
+
+static GLboolean
+vboxDDGetIntegerv(GLcontext *ctx, GLenum pname, GLint *result)
+{
+ cr_glGetIntegerv(pname, result);
+ return GL_TRUE;
+}
+
+static GLboolean
+vboxDDGetPointerv(GLcontext *ctx, GLenum pname, GLvoid **result)
+{
+ cr_glGetPointerv(pname, result);
+ return GL_TRUE;
+}
+
+/** @todo
+ * change stub's createcontext to reuse driver private part of mesa's ctx to store stub ctx info.
+ */
+#define VBOX_GL_FUNC(func) vboxDD_gl##func
+static void
+vboxdriInitFuncs(struct dd_function_table *driver)
+{
+ driver->GetString = VBOX_GL_FUNC(GetString);
+ driver->UpdateState = vboxDDUpdateState;
+#if 0
+ /* I assume that we don't need to change these. In that case, prefer the
+ * default implementation over a stub. */
+ driver->GetBufferSize = vboxDDGetBufferSize;
+ driver->ResizeBuffers = vboxDDResizeBuffer;
+ driver->Error = vboxDDError;
+#endif
+
+ driver->Finish = VBOX_GL_FUNC(Finish);
+ driver->Flush = VBOX_GL_FUNC(Flush);
+
+ /* framebuffer/image functions */
+ driver->Clear = VBOX_GL_FUNC(Clear);
+ driver->Accum = VBOX_GL_FUNC(Accum);
+ // driver->RasterPos = VBOX_GL_FUNC(RasterPos); /* No such element in *driver */
+ driver->DrawPixels = vboxDDDrawPixels;
+ driver->ReadPixels = vboxDDReadPixels;
+ driver->CopyPixels = vboxDDCopyPixels;
+ driver->Bitmap = vboxDDBitmap;
+
+ /* Texture functions */
+ /** @todo deal with texnames and gl_texture_object pointers which are passed here*/
+ driver->ChooseTextureFormat = NULL;
+ driver->TexImage1D = vboxDDTexImage1D;
+ driver->TexImage2D = vboxDDTexImage2D;
+ driver->TexImage3D = vboxDDTexImage3D;
+ driver->TexSubImage1D = vboxDDTexSubImage1D;
+ driver->TexSubImage2D = vboxDDTexSubImage2D;
+ driver->TexSubImage3D = vboxDDTexSubImage3D;
+ driver->GetTexImage = vboxDDGetTexImage;
+ driver->CopyTexImage1D = VBOX_GL_FUNC(CopyTexImage1D);
+ driver->CopyTexImage2D = VBOX_GL_FUNC(CopyTexImage2D);
+ driver->CopyTexSubImage1D = VBOX_GL_FUNC(CopyTexSubImage1D);
+ driver->CopyTexSubImage2D = VBOX_GL_FUNC(CopyTexSubImage2D);
+ driver->CopyTexSubImage3D = VBOX_GL_FUNC(CopyTexSubImage3D);
+ // driver->GenerateMipmap = VBOX_GL_FUNC(GenerateMipmap); /** @todo or NULL */
+ // driver->TestProxyTexImage = vboxDDTestProxyTexImage; /** @todo just pass to glTexImage as we take care or proxy textures there */
+ // driver->CompressedTexImage1D = VBOX_GL_FUNC(CompressedTexImage1D);
+ // driver->CompressedTexImage2D = VBOX_GL_FUNC(CompressedTexImage2D);
+ // driver->CompressedTexImage3D = VBOX_GL_FUNC(CompressedTexImage3D);
+ // driver->CompressedTexSubImage1D = VBOX_GL_FUNC(CompressedTexSubImage1D);
+ // driver->CompressedTexSubImage2D = VBOX_GL_FUNC(CompressedTexSubImage2D);
+ // driver->CompressedTexSubImage3D = VBOX_GL_FUNC(CompressedTexSubImage3D);
+ // driver->GetCompressedTexImage = VBOX_GL_FUNC(GetCompressedTexImage);
+ // driver->CompressedTextureSize = NULL; /** @todo */
+ driver->BindTexture = vboxDDBindTexture;
+ // driver->NewTextureObject = vboxDDNewTextureObject; /** @todo */
+ // driver->DeleteTexture = vboxDDDeleteTexture; /** @todo */
+ // driver->NewTextureImage = vboxDDNewTextureImage; /** @todo */
+ // driver->FreeTexImageData = vboxDDFreeTexImageData; /** @todo */
+ // driver->MapTexture = vboxDDMapTexture; /** @todo */
+ // driver->UnmapTexture = vboxDDUnmapTexture; /** @todo */
+ // driver->TextureMemCpy = vboxDDTextureMemCpy; /** @todo */
+ driver->IsTextureResident = vboxDDIsTextureResident;
+ driver->PrioritizeTexture = vboxDDPrioritizeTexture;
+ driver->ActiveTexture = VBOX_GL_FUNC(ActiveTextureARB);
+ // driver->UpdateTexturePalette = vboxDDUpdateTexturePalette; /** @todo */
+
+ /* imaging */
+ /*driver->CopyColorTable = _swrast_CopyColorTable;
+ driver->CopyColorSubTable = _swrast_CopyColorSubTable;
+ driver->CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
+ driver->CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;*/
+
+ /* Vertex/fragment programs */
+ driver->BindProgram = NULL;
+ // driver->NewProgram = _mesa_new_program; /** @todo */
+ // driver->DeleteProgram = _mesa_delete_program; /** @todo */
+ driver->ProgramStringNotify = NULL;
+#if FEATURE_MESA_program_debug
+ // driver->GetProgramRegister = _mesa_get_program_register; /** @todo */
+#endif /* FEATURE_MESA_program_debug */
+ driver->IsProgramNative = NULL;
+
+ /* simple state commands */
+ driver->AlphaFunc = VBOX_GL_FUNC(AlphaFunc);
+ driver->BlendColor = vboxDDBlendColor;
+ // driver->BlendEquationSeparate = VBOX_GL_FUNC(BlendEquationSeparate); /** @todo */
+ driver->BlendFuncSeparate = VBOX_GL_FUNC(BlendFuncSeparateEXT);
+ driver->ClearColor = vboxDDClearColor;
+ driver->ClearDepth = VBOX_GL_FUNC(ClearDepth);
+ driver->ClearIndex = vboxDDClearIndex;
+ driver->ClearStencil = VBOX_GL_FUNC(ClearStencil);
+ driver->ClipPlane = vboxDDClipPlane;
+ driver->ColorMask = VBOX_GL_FUNC(ColorMask);
+ driver->ColorMaterial = VBOX_GL_FUNC(ColorMaterial);
+ driver->CullFace = VBOX_GL_FUNC(CullFace);
+ driver->DrawBuffer = VBOX_GL_FUNC(DrawBuffer); /** @todo */
+ // driver->DrawBuffers = VBOX_GL_FUNC(DrawBuffers); /** @todo */
+ driver->FrontFace = VBOX_GL_FUNC(FrontFace);
+ driver->DepthFunc = VBOX_GL_FUNC(DepthFunc);
+ driver->DepthMask = VBOX_GL_FUNC(DepthMask);
+ driver->DepthRange = VBOX_GL_FUNC(DepthRange);
+ driver->Enable = vboxDDEnable;
+ driver->Fogfv = VBOX_GL_FUNC(Fogfv);
+ driver->Hint = VBOX_GL_FUNC(Hint);
+ driver->IndexMask = VBOX_GL_FUNC(IndexMask);
+ driver->Lightfv = VBOX_GL_FUNC(Lightfv);
+ driver->LightModelfv = VBOX_GL_FUNC(LightModelfv);
+ driver->LineStipple = VBOX_GL_FUNC(LineStipple);
+ driver->LineWidth = VBOX_GL_FUNC(LineWidth);
+ // driver->LogicOpcode = VBOX_GL_FUNC(LogicOpcode); /** @todo */
+ driver->PointParameterfv = VBOX_GL_FUNC(PointParameterfvARB);
+ driver->PointSize = VBOX_GL_FUNC(PointSize);
+ driver->PolygonMode = VBOX_GL_FUNC(PolygonMode);
+ driver->PolygonOffset = VBOX_GL_FUNC(PolygonOffset);
+ driver->PolygonStipple = VBOX_GL_FUNC(PolygonStipple);
+ driver->ReadBuffer = VBOX_GL_FUNC(ReadBuffer);
+ driver->RenderMode = vboxDDRenderMode;
+ driver->Scissor = VBOX_GL_FUNC(Scissor);
+ driver->ShadeModel = VBOX_GL_FUNC(ShadeModel);
+ // driver->StencilFuncSeparate = VBOX_GL_FUNC(StencilFuncSeparate); /** @todo */
+ // driver->StencilOpSeparate = VBOX_GL_FUNC(StencilOpSeparate); /** @todo */
+ // driver->StencilMaskSeparate = VBOX_GL_FUNC(StencilMaskSeparate); /** @todo */
+ driver->TexGen = VBOX_GL_FUNC(TexGenfv);
+ driver->TexEnv = VBOX_GL_FUNC(TexEnvfv);
+ driver->TexParameter = vboxDDTexParameter;
+ // driver->TextureMatrix = VBOX_GL_FUNC(TextureMatrix); /** @todo */
+ driver->Viewport = VBOX_GL_FUNC(Viewport);
+
+ /* vertex arrays */
+ driver->VertexPointer = VBOX_GL_FUNC(VertexPointer);
+ driver->NormalPointer = VBOX_GL_FUNC(NormalPointer);
+ driver->ColorPointer = VBOX_GL_FUNC(ColorPointer);
+ driver->FogCoordPointer = VBOX_GL_FUNC(FogCoordPointerEXT);
+ driver->IndexPointer = VBOX_GL_FUNC(IndexPointer);
+ driver->SecondaryColorPointer = VBOX_GL_FUNC(SecondaryColorPointerEXT);
+ driver->TexCoordPointer = VBOX_GL_FUNC(TexCoordPointer);
+ driver->EdgeFlagPointer = VBOX_GL_FUNC(EdgeFlagPointer);
+ // driver->VertexAttribPointer = VBOX_GL_FUNC(VertexAttribPointer); /** @todo */
+ // driver->LockArraysEXT = VBOX_GL_FUNC(LockArraysEXT); /** @todo */
+ // driver->UnlockArraysEXT = VBOX_GL_FUNC(UnlockArraysEXT); /** @todo */
+
+ /* state queries */
+ driver->GetBooleanv = vboxDDGetBooleanv;
+ driver->GetDoublev = vboxDDGetDoublev;
+ driver->GetFloatv = vboxDDGetFloatv;
+ driver->GetIntegerv = vboxDDGetIntegerv;
+ driver->GetPointerv = vboxDDGetPointerv;
+
+/** @todo */
+#if FEATURE_ARB_vertex_buffer_object
+ // driver->NewBufferObject = _mesa_new_buffer_object;
+ // driver->DeleteBuffer = _mesa_delete_buffer_object;
+ // driver->BindBuffer = NULL;
+ // driver->BufferData = _mesa_buffer_data;
+ // driver->BufferSubData = _mesa_buffer_subdata;
+ // driver->GetBufferSubData = _mesa_buffer_get_subdata;
+ // driver->MapBuffer = _mesa_buffer_map;
+ // driver->UnmapBuffer = _mesa_buffer_unmap;
+#endif
+
+/** @todo */
+#if FEATURE_EXT_framebuffer_object
+ // driver->NewFramebuffer = _mesa_new_framebuffer;
+ // driver->NewRenderbuffer = _mesa_new_soft_renderbuffer;
+ // driver->RenderTexture = _mesa_render_texture;
+ // driver->FinishRenderTexture = _mesa_finish_render_texture;
+ // driver->FramebufferRenderbuffer = _mesa_framebuffer_renderbuffer;
+#endif
+
+/** @todo */
+#if FEATURE_EXT_framebuffer_blit
+ // driver->BlitFramebuffer = _swrast_BlitFramebuffer;
+#endif
+
+ /* query objects */
+ // driver->NewQueryObject = VBOX_GL_FUNC(NewQueryObject); /** @todo */
+ // driver->DeleteQuery = VBOX_GL_FUNC(DeleteQuery); /** @todo */
+ // driver->BeginQuery = VBOX_GL_FUNC(BeginQuery); /** @todo */
+ // driver->EndQuery = VBOX_GL_FUNC(EndQuery); /** @todo */
+ // driver->WaitQuery = VBOX_GL_FUNC(WaitQuery); /** @todo */
+
+ /* APPLE_vertex_array_object */
+/*
+ driver->NewArrayObject = _mesa_new_array_object;
+ driver->DeleteArrayObject = _mesa_delete_array_object;
+ driver->BindArrayObject = NULL;
+*/
+
+ /* T&L stuff */
+ driver->NeedValidate = GL_FALSE;
+ driver->ValidateTnlModule = NULL;
+ driver->CurrentExecPrimitive = 0;
+ driver->CurrentSavePrimitive = 0;
+ driver->NeedFlush = 0;
+ driver->SaveNeedFlush = 0;
+
+ // driver->ProgramStringNotify = _tnl_program_string; /** @todo */
+ driver->FlushVertices = NULL;
+ driver->SaveFlushVertices = NULL;
+ driver->NotifySaveBegin = NULL;
+ driver->LightingSpaceChange = NULL;
+
+ /* display list */
+ driver->NewList = VBOX_GL_FUNC(NewList);
+ driver->EndList = VBOX_GL_FUNC(EndList);
+ // driver->BeginCallList = VBOX_GL_FUNC(BeginCallList); /** @todo */
+ // driver->EndCallList = VBOX_GL_FUNC(EndCallList); /** @todo */
+
+
+ /* shaders */
+ /*
+ driver->AttachShader = _mesa_attach_shader;
+ driver->BindAttribLocation = _mesa_bind_attrib_location;
+ driver->CompileShader = _mesa_compile_shader;
+ driver->CreateProgram = _mesa_create_program;
+ driver->CreateShader = _mesa_create_shader;
+ driver->DeleteProgram2 = _mesa_delete_program2;
+ driver->DeleteShader = _mesa_delete_shader;
+ driver->DetachShader = _mesa_detach_shader;
+ driver->GetActiveAttrib = _mesa_get_active_attrib;
+ driver->GetActiveUniform = _mesa_get_active_uniform;
+ driver->GetAttachedShaders = _mesa_get_attached_shaders;
+ driver->GetAttribLocation = _mesa_get_attrib_location;
+ driver->GetHandle = _mesa_get_handle;
+ driver->GetProgramiv = _mesa_get_programiv;
+ driver->GetProgramInfoLog = _mesa_get_program_info_log;
+ driver->GetShaderiv = _mesa_get_shaderiv;
+ driver->GetShaderInfoLog = _mesa_get_shader_info_log;
+ driver->GetShaderSource = _mesa_get_shader_source;
+ driver->GetUniformfv = _mesa_get_uniformfv;
+ driver->GetUniformiv = _mesa_get_uniformiv;
+ driver->GetUniformLocation = _mesa_get_uniform_location;
+ driver->IsProgram = _mesa_is_program;
+ driver->IsShader = _mesa_is_shader;
+ driver->LinkProgram = _mesa_link_program;
+ driver->ShaderSource = _mesa_shader_source;
+ driver->Uniform = _mesa_uniform;
+ driver->UniformMatrix = _mesa_uniform_matrix;
+ driver->UseProgram = _mesa_use_program;
+ driver->ValidateProgram = _mesa_validate_program;
+ */
+}
+
+static void
+vboxdriInitTnlVtxFmt(GLvertexformat *pVtxFmt)
+{
+ pVtxFmt->ArrayElement = VBOX_GL_FUNC(ArrayElement);
+ pVtxFmt->Begin = VBOX_GL_FUNC(Begin);
+ pVtxFmt->CallList = VBOX_GL_FUNC(CallList);
+ pVtxFmt->CallLists = VBOX_GL_FUNC(CallLists);
+ pVtxFmt->Color3f = VBOX_GL_FUNC(Color3f);
+ pVtxFmt->Color3fv = VBOX_GL_FUNC(Color3fv);
+ pVtxFmt->Color4f = VBOX_GL_FUNC(Color4f);
+ pVtxFmt->Color4fv = VBOX_GL_FUNC(Color4fv);
+ pVtxFmt->EdgeFlag = VBOX_GL_FUNC(EdgeFlag);
+ pVtxFmt->End = VBOX_GL_FUNC(End);
+ pVtxFmt->EvalCoord1f = VBOX_GL_FUNC(EvalCoord1f);
+ pVtxFmt->EvalCoord1fv = VBOX_GL_FUNC(EvalCoord1fv);
+ pVtxFmt->EvalCoord2f = VBOX_GL_FUNC(EvalCoord2f);
+ pVtxFmt->EvalCoord2fv = VBOX_GL_FUNC(EvalCoord2fv);
+ pVtxFmt->EvalPoint1 = VBOX_GL_FUNC(EvalPoint1);
+ pVtxFmt->EvalPoint2 = VBOX_GL_FUNC(EvalPoint2);
+ pVtxFmt->FogCoordfEXT = VBOX_GL_FUNC(FogCoordfEXT);
+ pVtxFmt->FogCoordfvEXT = VBOX_GL_FUNC(FogCoordfvEXT);
+ pVtxFmt->Indexf = VBOX_GL_FUNC(Indexf);
+ pVtxFmt->Indexfv = VBOX_GL_FUNC(Indexfv);
+ pVtxFmt->Materialfv = VBOX_GL_FUNC(Materialfv);
+ pVtxFmt->MultiTexCoord1fARB = VBOX_GL_FUNC(MultiTexCoord1fARB);
+ pVtxFmt->MultiTexCoord1fvARB = VBOX_GL_FUNC(MultiTexCoord1fvARB);
+ pVtxFmt->MultiTexCoord2fARB = VBOX_GL_FUNC(MultiTexCoord2fARB);
+ pVtxFmt->MultiTexCoord2fvARB = VBOX_GL_FUNC(MultiTexCoord2fvARB);
+ pVtxFmt->MultiTexCoord3fARB = VBOX_GL_FUNC(MultiTexCoord3fARB);
+ pVtxFmt->MultiTexCoord3fvARB = VBOX_GL_FUNC(MultiTexCoord3fvARB);
+ pVtxFmt->MultiTexCoord4fARB = VBOX_GL_FUNC(MultiTexCoord4fARB);
+ pVtxFmt->MultiTexCoord4fvARB = VBOX_GL_FUNC(MultiTexCoord4fvARB);
+ pVtxFmt->Normal3f = VBOX_GL_FUNC(Normal3f);
+ pVtxFmt->Normal3fv = VBOX_GL_FUNC(Normal3fv);
+ pVtxFmt->SecondaryColor3fEXT = VBOX_GL_FUNC(SecondaryColor3fEXT);
+ pVtxFmt->SecondaryColor3fvEXT = VBOX_GL_FUNC(SecondaryColor3fvEXT);
+ pVtxFmt->TexCoord1f = VBOX_GL_FUNC(TexCoord1f);
+ pVtxFmt->TexCoord1fv = VBOX_GL_FUNC(TexCoord1fv);
+ pVtxFmt->TexCoord2f = VBOX_GL_FUNC(TexCoord2f);
+ pVtxFmt->TexCoord2fv = VBOX_GL_FUNC(TexCoord2fv);
+ pVtxFmt->TexCoord3f = VBOX_GL_FUNC(TexCoord3f);
+ pVtxFmt->TexCoord3fv = VBOX_GL_FUNC(TexCoord3fv);
+ pVtxFmt->TexCoord4f = VBOX_GL_FUNC(TexCoord4f);
+ pVtxFmt->TexCoord4fv = VBOX_GL_FUNC(TexCoord4fv);
+ pVtxFmt->Vertex2f = VBOX_GL_FUNC(Vertex2f);
+ pVtxFmt->Vertex2fv = VBOX_GL_FUNC(Vertex2fv);
+ pVtxFmt->Vertex3f = VBOX_GL_FUNC(Vertex3f);
+ pVtxFmt->Vertex3fv = VBOX_GL_FUNC(Vertex3fv);
+ pVtxFmt->Vertex4f = VBOX_GL_FUNC(Vertex4f);
+ pVtxFmt->Vertex4fv = VBOX_GL_FUNC(Vertex4fv);
+ pVtxFmt->VertexAttrib1fNV = VBOX_GL_FUNC(VertexAttrib1fARB);
+ pVtxFmt->VertexAttrib1fvNV = VBOX_GL_FUNC(VertexAttrib1fvARB);
+ pVtxFmt->VertexAttrib2fNV = VBOX_GL_FUNC(VertexAttrib2fARB);
+ pVtxFmt->VertexAttrib2fvNV = VBOX_GL_FUNC(VertexAttrib2fvARB);
+ pVtxFmt->VertexAttrib3fNV = VBOX_GL_FUNC(VertexAttrib3fARB);
+ pVtxFmt->VertexAttrib3fvNV = VBOX_GL_FUNC(VertexAttrib3fvARB);
+ pVtxFmt->VertexAttrib4fNV = VBOX_GL_FUNC(VertexAttrib4fARB);
+ pVtxFmt->VertexAttrib4fvNV = VBOX_GL_FUNC(VertexAttrib4fvARB);
+ pVtxFmt->VertexAttrib1fARB = VBOX_GL_FUNC(VertexAttrib1fARB);
+ pVtxFmt->VertexAttrib1fvARB = VBOX_GL_FUNC(VertexAttrib1fvARB);
+ pVtxFmt->VertexAttrib2fARB = VBOX_GL_FUNC(VertexAttrib2fARB);
+ pVtxFmt->VertexAttrib2fvARB = VBOX_GL_FUNC(VertexAttrib2fvARB);
+ pVtxFmt->VertexAttrib3fARB = VBOX_GL_FUNC(VertexAttrib3fARB);
+ pVtxFmt->VertexAttrib3fvARB = VBOX_GL_FUNC(VertexAttrib3fvARB);
+ pVtxFmt->VertexAttrib4fARB = VBOX_GL_FUNC(VertexAttrib4fARB);
+ pVtxFmt->VertexAttrib4fvARB = VBOX_GL_FUNC(VertexAttrib4fvARB);
+
+ pVtxFmt->EvalMesh1 = VBOX_GL_FUNC(EvalMesh1);
+ pVtxFmt->EvalMesh2 = VBOX_GL_FUNC(EvalMesh2);
+ pVtxFmt->Rectf = VBOX_GL_FUNC(Rectf);
+
+ pVtxFmt->DrawArrays = VBOX_GL_FUNC(DrawArrays);
+ pVtxFmt->DrawElements = VBOX_GL_FUNC(DrawElements);
+ pVtxFmt->DrawRangeElements = VBOX_GL_FUNC(DrawRangeElements);
+}
+#undef VBOX_GL_FUNC
+
+static void
+vboxdriExtSetTexOffset(__DRIcontext *pDRICtx, GLint texname,
+ unsigned long long offset, GLint depth, GLuint pitch)
+{
+}
+
+
+static void
+vboxdriExtSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
+{
+}
+
+/** @todo not sure we need it from start*/
+static const __DRItexOffsetExtension vboxdriTexOffsetExtension = {
+ { __DRI_TEX_OFFSET },
+ vboxdriExtSetTexOffset,
+};
+
+/* This DRI extension is required to support EXT_texture_from_pixmap,
+ * which in turn is required by compiz.
+ */
+static const __DRItexBufferExtension vboxdriTexBufferExtension = {
+ { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
+ vboxdriExtSetTexBuffer,
+};
+
+/* List of DRI extensions supported by VBox DRI driver */
+static const __DRIextension *vboxdriExtensions[] = {
+ &vboxdriTexOffsetExtension.base,
+ &vboxdriTexBufferExtension.base,
+ NULL
+};
+
+static __GLcontextModes *vboxdriFillInModes(unsigned pixel_bits,
+ unsigned depth_bits,
+ unsigned stencil_bits,
+ GLboolean have_back_buffer)
+{
+ unsigned deep = (depth_bits > 17);
+
+ /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
+ * enough to add support. Basically, if a context is created with an
+ * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
+ * will never be used.
+ */
+
+ static const GLenum db_modes[2] = { GLX_NONE, GLX_SWAP_UNDEFINED_OML };
+ uint8_t depth_bits_array[4];
+ uint8_t stencil_bits_array[4];
+ if(deep) {
+ depth_bits_array[0] = 0;
+ depth_bits_array[1] = 24;
+ stencil_bits_array[0] = 0;
+ stencil_bits_array[1] = 8;
+ } else {
+ depth_bits_array[0] = depth_bits;
+ depth_bits_array[1] = 0;
+ depth_bits_array[2] = depth_bits;
+ depth_bits_array[3] = 0;
+ stencil_bits_array[0] = 0;
+ stencil_bits_array[1] = 0;
+ stencil_bits_array[2] = 8;
+ stencil_bits_array[3] = 8;
+ }
+
+ return driCreateConfigs(
+ deep ? GL_RGBA : GL_RGB,
+ deep ? GL_UNSIGNED_INT_8_8_8_8 : GL_UNSIGNED_SHORT_5_6_5,
+ depth_bits_array,
+ stencil_bits_array,
+ deep ? 2 : 4,
+ db_modes, 2);
+}
+
+/**
+ * This is the driver specific part of the createNewScreen entry point.
+ * Called when using legacy DRI.
+ *
+ * return the __GLcontextModes supported by this driver
+ */
+static const __DRIconfig **vboxdriInitScreen(__DRIscreenPrivate *psp)
+{
+ static const __DRIversion ddx_expected = { 1, 1, 0 };
+ static const __DRIversion dri_expected = { 4, 0, 0 };
+ static const __DRIversion drm_expected = { 1, 0, 0 };
+ //PVBoxDRI = (PVBoxDRI) psp->pDevPrivate;
+
+ /* Initialise our call table in chromium. */
+ if (!stubInit())
+ {
+ crDebug("vboxdriInitScreen: stubInit failed");
+ return NULL;
+ }
+
+ if ( ! driCheckDriDdxDrmVersions2( "tdfx",
+ &psp->dri_version, & dri_expected,
+ &psp->ddx_version, & ddx_expected,
+ &psp->drm_version, & drm_expected ) )
+ return NULL;
+
+ /* Calling driInitExtensions here, with a NULL context pointer,
+ * does not actually enable the extensions. It just makes sure
+ * that all the dispatch offsets for all the extensions that
+ * *might* be enables are known. This is needed because the
+ * dispatch offsets need to be known when _mesa_context_create is
+ * called, but we can't enable the extensions until we have a
+ * context pointer.
+ *
+ * Hello chicken. Hello egg. How are you two today?
+ */
+ vboxdriInitExtensions(NULL);
+
+ /** @todo check size of DRIRec (passed from X.Org driver), allocate private
+ * structure if necessary, parse options if necessary, map VRAM if
+ * necessary. */
+ psp->extensions = vboxdriExtensions;
+
+ /* Initialise VtxFmt call table. */
+ vboxdriInitTnlVtxFmt(&vboxdriTnlVtxFmt);
+
+ /*return (const __DRIconfig **)
+ vboxdriFillInModes(psp, dri_priv->cpp * 8,
+ (dri_priv->cpp == 2) ? 16 : 24,
+ (dri_priv->cpp == 2) ? 0 : 8, 1);*/
+
+ /** @todo This should depend on what the host can do, not the guest.
+ * However, we will probably want to discover that in the X.Org driver,
+ * not here. */
+ return (const __DRIconfig **) vboxdriFillInModes(psp, 24, 24, 8, 1);
+}
+
+static void
+vboxdriDestroyScreen(__DRIscreenPrivate * sPriv)
+{
+ crDebug("vboxdriDestroyScreen");
+#if 0 /* From the tdfx driver */
+ /* free all option information */
+ driDestroyOptionInfo (&sPriv->private->optionCache);
+ FREE(sPriv->private);
+ sPriv->private = NULL;
+#endif
+}
+
+static GLboolean
+vboxdriCreateContext(const __GLcontextModes * mesaVis,
+ __DRIcontextPrivate * driContextPriv,
+ void *sharedContextPrivate)
+{
+ //__DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
+ struct dd_function_table functions;
+ GLcontext *ctx, *shareCtx;
+
+#if 0 /* We shouldn't need this sort of thing. */
+ XVisualInfo *vis;
+ vis->visual->visualid;
+ context->dpy = dpy;
+ context->visual = vis;
+
+ GLXContext vboxctx = glXCreateContext(dpy, mesaVis->visualID, GL_TRUE);
+#endif
+ /* We should be allocating a private context structure, where we will
+ * remember the Mesa context (ctx) among other things. The TDFX driver
+ * also saves importand information in driContextPriv in there - is this
+ * not always available to us? */
+ //driContextPriv->driverPrivate = vboxctx;
+
+ /* Initialise the default driver functions then plug in our vbox ones,
+ * which will actually replace most of the defaults. */
+ /** @todo we should also pass some information from the visual back to the
+ * host. */
+ _mesa_init_driver_functions(&functions);
+ vboxdriInitFuncs(&functions);
+
+ /* Allocate context information for Mesa. */
+ if (sharedContextPrivate)
+ shareCtx = ((tdfxContextPtr) sharedContextPrivate)->glCtx;
+ else
+ shareCtx = NULL;
+ /** @todo save ctx, or be more confident that we can don't need to. */
+ ctx = _mesa_create_context(mesaVis, shareCtx, &functions,
+ driContextPriv->driverPrivate);
+ if (!ctx)
+ {
+ crDebug("vboxdriCreateContext: _mesa_create_context failed");
+ return GL_FALSE;
+ }
+
+ /* The TDFX driver parses its configuration files here, via
+ * driParseConfigFiles. We will probably get any information via guest
+ * properties. */
+
+ /* Set various context configuration. We take these values from the
+ * TDFX driver. */
+ /** @r=Leonid, stub.spu->dispatch_table.GetIntegerv(GL_MAX_TEXTURE_UNITS_ARB,&value) etc.
+ * Those would be cached where possible, see include/state/cr_limits.h, VBoxOGLgen/packspu_get.c
+ * Note, that ctx->Const.MaxTextureImageUnits is *not* related to GL_MAX_TEXTURE_UNITS_ARB,
+ * use GL_MAX_TEXTURE_IMAGE_UNITS_ARB instead.
+ * Also, those could fail if we haven't made ctx in our stub yet.
+ */
+ ctx->Const.MaxTextureLevels = 9;
+ ctx->Const.MaxTextureUnits = 1;
+ ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits;
+ ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits;
+
+ /* No wide points.
+ */
+ ctx->Const.MinPointSize = 1.0;
+ ctx->Const.MinPointSizeAA = 1.0;
+ ctx->Const.MaxPointSize = 1.0;
+ ctx->Const.MaxPointSizeAA = 1.0;
+
+ /* Disable wide lines as we can't antialias them correctly in
+ * hardware.
+ */
+ /** @note That applies to the TDFX, not to us, but as I don't yet know
+ * what to use instead I am leaving the values for now. */
+ ctx->Const.MinLineWidth = 1.0;
+ ctx->Const.MinLineWidthAA = 1.0;
+ ctx->Const.MaxLineWidth = 1.0;
+ ctx->Const.MaxLineWidthAA = 1.0;
+ ctx->Const.LineWidthGranularity = 1.0;
+
+ /* Initialize the software rasterizer and helper modules - again, TDFX */
+ _swrast_CreateContext( ctx );
+ _vbo_CreateContext( ctx );
+ _tnl_CreateContext( ctx );
+ _swsetup_CreateContext( ctx );
+
+ /* Install the customized pipeline, TDFX */
+ _tnl_destroy_pipeline( ctx );
+ _tnl_install_pipeline( ctx, tdfx_pipeline );
+
+ /* Configure swrast and T&L to match hardware characteristics, TDFX */
+ _swrast_allow_pixel_fog( ctx, GL_TRUE );
+ _swrast_allow_vertex_fog( ctx, GL_FALSE );
+ _tnl_allow_pixel_fog( ctx, GL_TRUE );
+ _tnl_allow_vertex_fog( ctx, GL_FALSE );
+ /*ctx->DriverCtx = ;*/
+
+ /* This was *not* in the TDFX driver. */
+ _mesa_install_exec_vtxfmt(ctx, &vboxdriTnlVtxFmt);
+
+ vboxdriInitExtensions(ctx);
+
+ return GL_TRUE;
+}
+
+
+static void
+vboxdriDestroyContext(__DRIcontextPrivate *driContextPriv)
+{
+ // glXDestroyContext(driContextPriv->driverPrivate);
+ //_mesa_destroy_context ?
+}
+
+/**
+ * This is called when we need to set up GL rendering to a new X window.
+ */
+static GLboolean
+vboxdriCreateBuffer(__DRIscreenPrivate * driScrnPriv,
+ __DRIdrawablePrivate * driDrawPriv,
+ const __GLcontextModes * mesaVis, GLboolean isPixmap)
+{
+ return GL_FALSE;
+}
+
+static void
+vboxdriDestroyBuffer(__DRIdrawablePrivate * driDrawPriv)
+{
+}
+
+static void
+vboxdriSwapBuffers(__DRIdrawablePrivate * dPriv)
+{
+}
+
+
+GLboolean
+vboxdriMakeCurrent(__DRIcontextPrivate * driContextPriv,
+ __DRIdrawablePrivate * driDrawPriv,
+ __DRIdrawablePrivate * driReadPriv)
+{
+ return GL_FALSE;
+}
+
+GLboolean
+vboxdriUnbindContext(__DRIcontextPrivate * driContextPriv)
+{
+ return GL_TRUE;
+}
+
+
+/* This structure is used by dri_util from mesa, don't rename it! */
+DECLEXPORT(const struct __DriverAPIRec) driDriverAPI = {
+ .InitScreen = vboxdriInitScreen,
+ .DestroyScreen = vboxdriDestroyScreen,
+ .CreateContext = vboxdriCreateContext,
+ .DestroyContext = vboxdriDestroyContext,
+ .CreateBuffer = vboxdriCreateBuffer,
+ .DestroyBuffer = vboxdriDestroyBuffer,
+ .SwapBuffers = vboxdriSwapBuffers,
+ .MakeCurrent = vboxdriMakeCurrent,
+ .UnbindContext = vboxdriUnbindContext,
+ .GetSwapInfo = NULL,
+ .WaitForMSC = NULL,
+ .WaitForSBC = NULL,
+ .SwapBuffersMSC = NULL,
+ .CopySubBuffer = NULL,
+ .GetDrawableMSC = NULL,
+ .InitScreen2 = NULL
+};
diff --git a/src/VBox/Additions/common/crOpenGL/dri_drv.h b/src/VBox/Additions/common/crOpenGL/dri_drv.h
new file mode 100644
index 00000000..7c11c3ba
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/dri_drv.h
@@ -0,0 +1,32 @@
+/* $Id: dri_drv.h $ */
+
+/** @file
+ *
+ * VirtualBox guest OpenGL DRI header
+ */
+
+/*
+ * Copyright (C) 2009-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef GA_INCLUDED_SRC_common_crOpenGL_dri_drv_h
+#define GA_INCLUDED_SRC_common_crOpenGL_dri_drv_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "src/mesa/main/mtypes.h"
+#include "src/mesa/drivers/dri/common/dri_util.h"
+#include "src/mesa/glapi/dispatch.h"
+#include "src/mesa/main/dd.h"
+
+#endif /* !GA_INCLUDED_SRC_common_crOpenGL_dri_drv_h */
+
diff --git a/src/VBox/Additions/common/crOpenGL/dri_glx.h b/src/VBox/Additions/common/crOpenGL/dri_glx.h
new file mode 100644
index 00000000..237c93a3
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/dri_glx.h
@@ -0,0 +1,165 @@
+/* $Id: dri_glx.h $ */
+
+/** @file
+ *
+ * VirtualBox guest OpenGL DRI GLX header
+ */
+
+/*
+ * Copyright (C) 2009-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef GA_INCLUDED_SRC_common_crOpenGL_dri_glx_h
+#define GA_INCLUDED_SRC_common_crOpenGL_dri_glx_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "chromium.h"
+#include "stub.h"
+
+#if defined(VBOXOGL_FAKEDRI) || defined(VBOXOGL_DRI)
+ #define VBOXGLXTAG(Func) vboxstub_##Func
+ #define VBOXGLXENTRYTAG(Func) vbox_##Func
+ #define VBOXGLTAG(Func) cr_##Func
+#else
+ #define VBOXGLXTAG(Func) Func
+ #define VBOXGLXENTRYTAG(Func) Func
+ #define VBOXGLTAG(Func) Func
+#endif
+
+#ifdef VBOXOGL_FAKEDRI
+extern DECLEXPORT(const char *) VBOXGLXTAG(glXGetDriverConfig)(const char *driverName);
+extern DECLEXPORT(void) VBOXGLXTAG(glXFreeMemoryMESA)(Display *dpy, int scrn, void *pointer);
+extern DECLEXPORT(GLXContext) VBOXGLXTAG(glXImportContextEXT)(Display *dpy, GLXContextID contextID);
+extern DECLEXPORT(GLXContextID) VBOXGLXTAG(glXGetContextIDEXT)(const GLXContext ctx);
+extern DECLEXPORT(Bool) VBOXGLXTAG(glXMakeCurrentReadSGI)(Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
+extern DECLEXPORT(const char *) VBOXGLXTAG(glXGetScreenDriver)(Display *dpy, int scrNum);
+extern DECLEXPORT(Display *) VBOXGLXTAG(glXGetCurrentDisplayEXT)(void);
+extern DECLEXPORT(void) VBOXGLXTAG(glXFreeContextEXT)(Display *dpy, GLXContext ctx);
+/*Mesa internal*/
+extern DECLEXPORT(int) VBOXGLXTAG(glXQueryContextInfoEXT)(Display *dpy, GLXContext ctx);
+extern DECLEXPORT(void *) VBOXGLXTAG(glXAllocateMemoryMESA)(Display *dpy, int scrn,
+ size_t size, float readFreq,
+ float writeFreq, float priority);
+extern DECLEXPORT(GLuint) VBOXGLXTAG(glXGetMemoryOffsetMESA)(Display *dpy, int scrn, const void *pointer );
+extern DECLEXPORT(GLXPixmap) VBOXGLXTAG(glXCreateGLXPixmapMESA)(Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap);
+#endif
+
+/*Common glX functions*/
+extern DECLEXPORT(void) VBOXGLXTAG(glXCopyContext)( Display *dpy, GLXContext src, GLXContext dst,
+#if defined(SunOS)
+unsigned long mask);
+#else
+unsigned long mask);
+#endif
+extern DECLEXPORT(void) VBOXGLXTAG(glXUseXFont)(Font font, int first, int count, int listBase);
+extern DECLEXPORT(CR_GLXFuncPtr) VBOXGLXTAG(glXGetProcAddress)(const GLubyte *name);
+extern DECLEXPORT(Bool) VBOXGLXTAG(glXQueryExtension)(Display *dpy, int *errorBase, int *eventBase);
+extern DECLEXPORT(Bool) VBOXGLXTAG(glXIsDirect)(Display *dpy, GLXContext ctx);
+extern DECLEXPORT(GLXPixmap) VBOXGLXTAG(glXCreateGLXPixmap)(Display *dpy, XVisualInfo *vis, Pixmap pixmap);
+extern DECLEXPORT(void) VBOXGLXTAG(glXSwapBuffers)(Display *dpy, GLXDrawable drawable);
+extern DECLEXPORT(GLXDrawable) VBOXGLXTAG(glXGetCurrentDrawable)(void);
+extern DECLEXPORT(void) VBOXGLXTAG(glXWaitGL)(void);
+extern DECLEXPORT(Display *) VBOXGLXTAG(glXGetCurrentDisplay)(void);
+extern DECLEXPORT(const char *) VBOXGLXTAG(glXQueryServerString)(Display *dpy, int screen, int name);
+extern DECLEXPORT(GLXContext) VBOXGLXTAG(glXCreateContext)(Display *dpy, XVisualInfo *vis, GLXContext share, Bool direct);
+extern DECLEXPORT(int) VBOXGLXTAG(glXGetConfig)(Display *dpy, XVisualInfo *vis, int attrib, int *value);
+extern DECLEXPORT(void) VBOXGLXTAG(glXWaitX)(void);
+extern DECLEXPORT(GLXContext) VBOXGLXTAG(glXGetCurrentContext)(void);
+extern DECLEXPORT(const char *) VBOXGLXTAG(glXGetClientString)(Display *dpy, int name);
+extern DECLEXPORT(Bool) VBOXGLXTAG(glXMakeCurrent)(Display *dpy, GLXDrawable drawable, GLXContext ctx);
+extern DECLEXPORT(void) VBOXGLXTAG(glXDestroyContext)(Display *dpy, GLXContext ctx);
+extern DECLEXPORT(CR_GLXFuncPtr) VBOXGLXTAG(glXGetProcAddressARB)(const GLubyte *name);
+extern DECLEXPORT(void) VBOXGLXTAG(glXDestroyGLXPixmap)(Display *dpy, GLXPixmap pix);
+extern DECLEXPORT(Bool) VBOXGLXTAG(glXQueryVersion)(Display *dpy, int *major, int *minor);
+extern DECLEXPORT(XVisualInfo *) VBOXGLXTAG(glXChooseVisual)(Display *dpy, int screen, int *attribList);
+extern DECLEXPORT(const char *) VBOXGLXTAG(glXQueryExtensionsString)(Display *dpy, int screen);
+
+/**
+ * Set this to 1 if you want to build stub functions for the
+ * GL_SGIX_pbuffer and GLX_SGIX_fbconfig extensions.
+ * This used to be disabled, due to "messy compilation issues",
+ * according to the earlier comment; but they're needed just
+ * to resolve symbols for OpenInventor applications, and I
+ * haven't found any reference to exactly what the "messy compilation
+ * issues" are, so I'm re-enabling the code by default.
+ */
+#define GLX_EXTRAS 1
+
+#define GLX_SGIX_video_resize 1
+
+/**
+ * Prototypes, in case they're not in glx.h or glxext.h
+ * Unfortunately, there's some inconsistency between the extension
+ * specs, and the SGI, NVIDIA, XFree86 and common glxext.h header
+ * files.
+ */
+#if defined(GLX_GLXEXT_VERSION)
+/* match glxext.h, XFree86, Mesa */
+#define ATTRIB_TYPE const int
+#else
+#define ATTRIB_TYPE int
+#endif
+
+#if GLX_EXTRAS
+extern DECLEXPORT(GLXPbufferSGIX) VBOXGLXTAG(glXCreateGLXPbufferSGIX)
+(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list);
+
+extern DECLEXPORT(int) VBOXGLXTAG(glXQueryGLXPbufferSGIX)
+(Display *dpy, GLXPbuffer pbuf, int attribute, unsigned int *value);
+
+extern DECLEXPORT(GLXFBConfigSGIX *) VBOXGLXTAG(glXChooseFBConfigSGIX)
+(Display *dpy, int screen, int *attrib_list, int *nelements);
+
+extern DECLEXPORT(void) VBOXGLXTAG(glXDestroyGLXPbufferSGIX)(Display *dpy, GLXPbuffer pbuf);
+extern DECLEXPORT(void) VBOXGLXTAG(glXSelectEventSGIX)(Display *dpy, GLXDrawable drawable, unsigned long mask);
+extern DECLEXPORT(void) VBOXGLXTAG(glXGetSelectedEventSGIX)(Display *dpy, GLXDrawable drawable, unsigned long *mask);
+
+extern DECLEXPORT(GLXFBConfigSGIX) VBOXGLXTAG(glXGetFBConfigFromVisualSGIX)(Display *dpy, XVisualInfo *vis);
+extern DECLEXPORT(XVisualInfo *) VBOXGLXTAG(glXGetVisualFromFBConfigSGIX)(Display *dpy, GLXFBConfig config);
+extern DECLEXPORT(GLXContext) VBOXGLXTAG(glXCreateContextWithConfigSGIX)
+(Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
+
+extern DECLEXPORT(GLXPixmap) VBOXGLXTAG(glXCreateGLXPixmapWithConfigSGIX)(Display *dpy, GLXFBConfig config, Pixmap pixmap);
+extern DECLEXPORT(int) VBOXGLXTAG(glXGetFBConfigAttribSGIX)(Display *dpy, GLXFBConfig config, int attribute, int *value);
+
+/*
+ * GLX 1.3 functions
+ */
+extern DECLEXPORT(GLXFBConfig *) VBOXGLXTAG(glXChooseFBConfig)(Display *dpy, int screen, ATTRIB_TYPE *attrib_list, int *nelements);
+extern DECLEXPORT(GLXPbuffer) VBOXGLXTAG(glXCreatePbuffer)(Display *dpy, GLXFBConfig config, ATTRIB_TYPE *attrib_list);
+extern DECLEXPORT(GLXPixmap) VBOXGLXTAG(glXCreatePixmap)(Display *dpy, GLXFBConfig config, Pixmap pixmap, ATTRIB_TYPE *attrib_list);
+extern DECLEXPORT(GLXWindow) VBOXGLXTAG(glXCreateWindow)(Display *dpy, GLXFBConfig config, Window win, ATTRIB_TYPE *attrib_list);
+extern DECLEXPORT(GLXContext) VBOXGLXTAG(glXCreateNewContext)
+(Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
+
+extern DECLEXPORT(void) VBOXGLXTAG(glXDestroyPbuffer)(Display *dpy, GLXPbuffer pbuf);
+extern DECLEXPORT(void) VBOXGLXTAG(glXDestroyPixmap)(Display *dpy, GLXPixmap pixmap);
+extern DECLEXPORT(void) VBOXGLXTAG(glXDestroyWindow)(Display *dpy, GLXWindow win);
+extern DECLEXPORT(GLXDrawable) VBOXGLXTAG(glXGetCurrentReadDrawable)(void);
+extern DECLEXPORT(int) VBOXGLXTAG(glXGetFBConfigAttrib)(Display *dpy, GLXFBConfig config, int attribute, int *value);
+extern DECLEXPORT(GLXFBConfig *) VBOXGLXTAG(glXGetFBConfigs)(Display *dpy, int screen, int *nelements);
+extern DECLEXPORT(void) VBOXGLXTAG(glXGetSelectedEvent)(Display *dpy, GLXDrawable draw, unsigned long *event_mask);
+extern DECLEXPORT(XVisualInfo *) VBOXGLXTAG(glXGetVisualFromFBConfig)(Display *dpy, GLXFBConfig config);
+extern DECLEXPORT(Bool) VBOXGLXTAG(glXMakeContextCurrent)(Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
+extern DECLEXPORT(int) VBOXGLXTAG(glXQueryContext)(Display *dpy, GLXContext ctx, int attribute, int *value);
+extern DECLEXPORT(void) VBOXGLXTAG(glXQueryDrawable)(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value);
+extern DECLEXPORT(void) VBOXGLXTAG(glXSelectEvent)(Display *dpy, GLXDrawable draw, unsigned long event_mask);
+
+#ifdef CR_EXT_texture_from_pixmap
+extern DECLEXPORT(void) VBOXGLXTAG(glXBindTexImageEXT)(Display *dpy, GLXDrawable draw, int buffer, const int *attrib_list);
+extern DECLEXPORT(void) VBOXGLXTAG(glXReleaseTexImageEXT)(Display *dpy, GLXDrawable draw, int buffer);
+#endif
+
+#endif /* GLX_EXTRAS */
+
+#endif /* !GA_INCLUDED_SRC_common_crOpenGL_dri_glx_h */
diff --git a/src/VBox/Additions/common/crOpenGL/dri_util.c b/src/VBox/Additions/common/crOpenGL/dri_util.c
new file mode 100644
index 00000000..5041e07f
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/dri_util.c
@@ -0,0 +1,1117 @@
+/* $XFree86: xc/lib/GL/dri/dri_util.c,v 1.7 2003/04/28 17:01:25 dawes Exp $ */
+/**
+ * \file dri_util.c
+ * DRI utility functions.
+ *
+ * This module acts as glue between GLX and the actual hardware driver. A DRI
+ * driver doesn't really \e have to use any of this - it's optional. But, some
+ * useful stuff is done here that otherwise would have to be duplicated in most
+ * drivers.
+ *
+ * Basically, these utility functions take care of some of the dirty details of
+ * screen initialization, context creation, context binding, DRM setup, etc.
+ *
+ * These functions are compiled into each DRI driver so libGL.so knows nothing
+ * about them.
+ */
+
+
+#include <assert.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <stdio.h>
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *)-1)
+#endif
+
+#include "imports.h"
+#define None 0
+
+#include "dri_util.h"
+#include "drm_sarea.h"
+#include "utils.h"
+
+#ifndef GLX_OML_sync_control
+typedef GLboolean ( * PFNGLXGETMSCRATEOMLPROC) (__DRIdrawable *drawable, int32_t *numerator, int32_t *denominator);
+#endif
+
+/**
+ * This is just a token extension used to signal that the driver
+ * supports setting a read drawable.
+ */
+const __DRIextension driReadDrawableExtension = {
+ __DRI_READ_DRAWABLE, __DRI_READ_DRAWABLE_VERSION
+};
+
+/**
+ * Print message to \c stderr if the \c LIBGL_DEBUG environment variable
+ * is set.
+ *
+ * Is called from the drivers.
+ *
+ * \param f \c printf like format string.
+ */
+void
+__driUtilMessage(const char *f, ...)
+{
+ va_list args;
+
+ if (getenv("LIBGL_DEBUG")) {
+ fprintf(stderr, "libGL error: \n");
+ va_start(args, f);
+ vfprintf(stderr, f, args);
+ va_end(args);
+ fprintf(stderr, "\n");
+ }
+}
+
+GLint
+driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 )
+{
+ if (rect2.x1 > rect1.x1) rect1.x1 = rect2.x1;
+ if (rect2.x2 < rect1.x2) rect1.x2 = rect2.x2;
+ if (rect2.y1 > rect1.y1) rect1.y1 = rect2.y1;
+ if (rect2.y2 < rect1.y2) rect1.y2 = rect2.y2;
+
+ if (rect1.x1 > rect1.x2 || rect1.y1 > rect1.y2) return 0;
+
+ return (rect1.x2 - rect1.x1) * (rect1.y2 - rect1.y1);
+}
+
+/*****************************************************************/
+/** \name Context (un)binding functions */
+/*****************************************************************/
+/*@{*/
+
+/**
+ * Unbind context.
+ *
+ * \param scrn the screen.
+ * \param gc context.
+ *
+ * \return \c GL_TRUE on success, or \c GL_FALSE on failure.
+ *
+ * \internal
+ * This function calls __DriverAPIRec::UnbindContext, and then decrements
+ * __DRIdrawablePrivateRec::refcount which must be non-zero for a successful
+ * return.
+ *
+ * While casting the opaque private pointers associated with the parameters
+ * into their respective real types it also assures they are not \c NULL.
+ */
+static int driUnbindContext(__DRIcontext *pcp)
+{
+ __DRIscreen *psp;
+ __DRIdrawable *pdp;
+ __DRIdrawable *prp;
+
+ /*
+ ** Assume error checking is done properly in glXMakeCurrent before
+ ** calling driUnbindContext.
+ */
+
+ if (pcp == NULL)
+ return GL_FALSE;
+
+ psp = pcp->driScreenPriv;
+ pdp = pcp->driDrawablePriv;
+ prp = pcp->driReadablePriv;
+
+ /* Let driver unbind drawable from context */
+ (*psp->DriverAPI.UnbindContext)(pcp);
+
+ if (pdp->refcount == 0) {
+ /* ERROR!!! */
+ return GL_FALSE;
+ }
+
+ pdp->refcount--;
+
+ if (prp != pdp) {
+ if (prp->refcount == 0) {
+ /* ERROR!!! */
+ return GL_FALSE;
+ }
+
+ prp->refcount--;
+ }
+
+
+ /* XXX this is disabled so that if we call SwapBuffers on an unbound
+ * window we can determine the last context bound to the window and
+ * use that context's lock. (BrianP, 2-Dec-2000)
+ */
+#if 0
+ /* Unbind the drawable */
+ pcp->driDrawablePriv = NULL;
+ pdp->driContextPriv = &psp->dummyContextPriv;
+#endif
+
+ return GL_TRUE;
+}
+
+
+/**
+ * This function takes both a read buffer and a draw buffer. This is needed
+ * for \c glXMakeCurrentReadSGI or GLX 1.3's \c glXMakeContextCurrent
+ * function.
+ */
+static int driBindContext(__DRIcontext *pcp,
+ __DRIdrawable *pdp,
+ __DRIdrawable *prp)
+{
+ __DRIscreenPrivate *psp;
+
+ /*
+ ** Assume error checking is done properly in glXMakeCurrent before
+ ** calling driBindContext.
+ */
+
+ if (pcp == NULL || pdp == None || prp == None)
+ return GL_FALSE;
+
+ /* Bind the drawable to the context */
+ pcp->driDrawablePriv = pdp;
+ pcp->driReadablePriv = prp;
+ pdp->driContextPriv = pcp;
+ pdp->refcount++;
+ if ( pdp != prp ) {
+ prp->refcount++;
+ }
+
+ /*
+ ** Now that we have a context associated with this drawable, we can
+ ** initialize the drawable information if has not been done before.
+ */
+
+ psp = pcp->driScreenPriv;
+ if (psp->dri2.enabled) {
+ __driParseEvents(pcp, pdp);
+ __driParseEvents(pcp, prp);
+ } else {
+ if (!pdp->pStamp || *pdp->pStamp != pdp->lastStamp) {
+ DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
+ __driUtilUpdateDrawableInfo(pdp);
+ DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
+ }
+
+ if ((pdp != prp) && (!prp->pStamp || *prp->pStamp != prp->lastStamp)) {
+ DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
+ __driUtilUpdateDrawableInfo(prp);
+ DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
+ }
+ }
+
+ /* Call device-specific MakeCurrent */
+ (*psp->DriverAPI.MakeCurrent)(pcp, pdp, prp);
+
+ return GL_TRUE;
+}
+
+/*@}*/
+
+
+/*****************************************************************/
+/** \name Drawable handling functions */
+/*****************************************************************/
+/*@{*/
+
+/**
+ * Update private drawable information.
+ *
+ * \param pdp pointer to the private drawable information to update.
+ *
+ * This function basically updates the __DRIdrawablePrivate struct's
+ * cliprect information by calling \c __DRIinterfaceMethods::getDrawableInfo.
+ * This is usually called by the DRI_VALIDATE_DRAWABLE_INFO macro which
+ * compares the __DRIdrwablePrivate pStamp and lastStamp values. If
+ * the values are different that means we have to update the clipping
+ * info.
+ */
+void
+__driUtilUpdateDrawableInfo(__DRIdrawablePrivate *pdp)
+{
+ __DRIscreenPrivate *psp = pdp->driScreenPriv;
+ __DRIcontextPrivate *pcp = pdp->driContextPriv;
+
+ if (!pcp
+ || ((pdp != pcp->driDrawablePriv) && (pdp != pcp->driReadablePriv))) {
+ /* ERROR!!!
+ * ...but we must ignore it. There can be many contexts bound to a
+ * drawable.
+ */
+ }
+
+ if (pdp->pClipRects) {
+ _mesa_free(pdp->pClipRects);
+ pdp->pClipRects = NULL;
+ }
+
+ if (pdp->pBackClipRects) {
+ _mesa_free(pdp->pBackClipRects);
+ pdp->pBackClipRects = NULL;
+ }
+
+ DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
+
+ if (! (*psp->getDrawableInfo->getDrawableInfo)(pdp,
+ &pdp->index, &pdp->lastStamp,
+ &pdp->x, &pdp->y, &pdp->w, &pdp->h,
+ &pdp->numClipRects, &pdp->pClipRects,
+ &pdp->backX,
+ &pdp->backY,
+ &pdp->numBackClipRects,
+ &pdp->pBackClipRects,
+ pdp->loaderPrivate)) {
+ /* Error -- eg the window may have been destroyed. Keep going
+ * with no cliprects.
+ */
+ pdp->pStamp = &pdp->lastStamp; /* prevent endless loop */
+ pdp->numClipRects = 0;
+ pdp->pClipRects = NULL;
+ pdp->numBackClipRects = 0;
+ pdp->pBackClipRects = NULL;
+ }
+ else
+ pdp->pStamp = &(psp->pSAREA->drawableTable[pdp->index].stamp);
+
+ DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
+}
+
+
+int
+__driParseEvents(__DRIcontextPrivate *pcp, __DRIdrawablePrivate *pdp)
+{
+ __DRIscreenPrivate *psp = pdp->driScreenPriv;
+ __DRIDrawableConfigEvent *dc, *last_dc;
+ __DRIBufferAttachEvent *ba, *last_ba;
+ unsigned int tail, mask, *p, end, total, size, changed;
+ unsigned char *data;
+ size_t rect_size;
+
+ /* Check for wraparound. */
+ if (pcp && psp->dri2.buffer->prealloc - pdp->dri2.tail > psp->dri2.buffer->size) {
+ /* If prealloc overlaps into what we just parsed, the
+ * server overwrote it and we have to reset our tail
+ * pointer. */
+ DRM_UNLOCK(psp->fd, psp->lock, pcp->hHWContext);
+ (*psp->dri2.loader->reemitDrawableInfo)(pdp, &pdp->dri2.tail,
+ pdp->loaderPrivate);
+ DRM_LIGHT_LOCK(psp->fd, psp->lock, pcp->hHWContext);
+ }
+
+ total = psp->dri2.buffer->head - pdp->dri2.tail;
+ mask = psp->dri2.buffer->size - 1;
+ end = psp->dri2.buffer->head;
+ data = psp->dri2.buffer->data;
+
+ changed = 0;
+ last_dc = NULL;
+ last_ba = NULL;
+
+ for (tail = pdp->dri2.tail; tail != end; tail += size) {
+ p = (unsigned int *) (data + (tail & mask));
+ size = DRI2_EVENT_SIZE(*p);
+ if (size > total || (tail & mask) + size > psp->dri2.buffer->size) {
+ /* illegal data, bail out. */
+ fprintf(stderr, "illegal event size\n");
+ break;
+ }
+
+ switch (DRI2_EVENT_TYPE(*p)) {
+ case DRI2_EVENT_DRAWABLE_CONFIG:
+ dc = (__DRIDrawableConfigEvent *) p;
+ if (dc->drawable == pdp->dri2.drawable_id)
+ last_dc = dc;
+ break;
+
+ case DRI2_EVENT_BUFFER_ATTACH:
+ ba = (__DRIBufferAttachEvent *) p;
+ if (ba->drawable == pdp->dri2.drawable_id &&
+ ba->buffer.attachment == DRI_DRAWABLE_BUFFER_FRONT_LEFT)
+ last_ba = ba;
+ break;
+ }
+ }
+
+ if (last_dc) {
+ if (pdp->w != last_dc->width || pdp->h != last_dc->height)
+ changed = 1;
+
+ pdp->x = last_dc->x;
+ pdp->y = last_dc->y;
+ pdp->w = last_dc->width;
+ pdp->h = last_dc->height;
+
+ pdp->backX = 0;
+ pdp->backY = 0;
+ pdp->numBackClipRects = 1;
+ pdp->pBackClipRects[0].x1 = 0;
+ pdp->pBackClipRects[0].y1 = 0;
+ pdp->pBackClipRects[0].x2 = pdp->w;
+ pdp->pBackClipRects[0].y2 = pdp->h;
+
+ pdp->numClipRects = last_dc->num_rects;
+ _mesa_free(pdp->pClipRects);
+ rect_size = last_dc->num_rects * sizeof last_dc->rects[0];
+ pdp->pClipRects = _mesa_malloc(rect_size);
+ memcpy(pdp->pClipRects, last_dc->rects, rect_size);
+ }
+
+ /* We only care about the most recent drawable config. */
+ if (last_dc && changed)
+ (*psp->DriverAPI.HandleDrawableConfig)(pdp, pcp, last_dc);
+
+ /* Front buffer attachments are special, they typically mean that
+ * we're rendering to a redirected window (or a child window of a
+ * redirected window) and that it got resized. Resizing the root
+ * window on randr events is a special case of this. Other causes
+ * may be a window transitioning between redirected and
+ * non-redirected, or a window getting reparented between parents
+ * with different window pixmaps (eg two redirected windows).
+ * These events are special in that the X server allocates the
+ * buffer and that the buffer may be shared by other child
+ * windows. When our window share the window pixmap with its
+ * parent, drawable config events doesn't affect the front buffer.
+ * We only care about the last such event in the buffer; in fact,
+ * older events will refer to invalid buffer objects.*/
+ if (last_ba)
+ (*psp->DriverAPI.HandleBufferAttach)(pdp, pcp, last_ba);
+
+ /* If there was a drawable config event in the buffer and it
+ * changed the size of the window, all buffer auxiliary buffer
+ * attachments prior to that are invalid (as opposed to the front
+ * buffer case discussed above). In that case we can start
+ * looking for buffer attachment after the last drawable config
+ * event. If there is no drawable config event in this batch of
+ * events, we have to assume that the last batch might have had
+ * one and process all buffer attach events.*/
+ if (last_dc && changed)
+ tail = (unsigned char *) last_dc - data;
+ else
+ tail = pdp->dri2.tail;
+
+ for ( ; tail != end; tail += size) {
+ ba = (__DRIBufferAttachEvent *) (data + (tail & mask));
+ size = DRI2_EVENT_SIZE(ba->event_header);
+
+ if (DRI2_EVENT_TYPE(ba->event_header) != DRI2_EVENT_BUFFER_ATTACH)
+ continue;
+ if (ba->drawable != pdp->dri2.drawable_id)
+ continue;
+ if (last_ba == ba)
+ continue;
+
+ (*psp->DriverAPI.HandleBufferAttach)(pdp, pcp, ba);
+ changed = 1;
+ }
+
+ pdp->dri2.tail = tail;
+
+ return changed || last_ba;
+}
+
+/*@}*/
+
+/*****************************************************************/
+/** \name GLX callbacks */
+/*****************************************************************/
+/*@{*/
+
+static void driReportDamage(__DRIdrawable *pdp,
+ struct drm_clip_rect *pClipRects, int numClipRects)
+{
+ __DRIscreen *psp = pdp->driScreenPriv;
+
+ /* Check that we actually have the new damage report method */
+ if (psp->dri2.enabled) {
+ (*psp->dri2.loader->postDamage)(pdp,
+ pClipRects,
+ numClipRects,
+ pdp->loaderPrivate);
+ } else if (psp->damage) {
+ /* Report the damage. Currently, all our drivers draw
+ * directly to the front buffer, so we report the damage there
+ * rather than to the backing storein (if any).
+ */
+ (*psp->damage->reportDamage)(pdp,
+ pdp->x, pdp->y,
+ pClipRects, numClipRects,
+ GL_TRUE, pdp->loaderPrivate);
+ }
+}
+
+
+/**
+ * Swap buffers.
+ *
+ * \param drawablePrivate opaque pointer to the per-drawable private info.
+ *
+ * \internal
+ * This function calls __DRIdrawablePrivate::swapBuffers.
+ *
+ * Is called directly from glXSwapBuffers().
+ */
+static void driSwapBuffers(__DRIdrawable *dPriv)
+{
+ __DRIscreen *psp = dPriv->driScreenPriv;
+
+ if (!dPriv->numClipRects)
+ return;
+
+ if (psp->dri2.enabled)
+ __driParseEvents(NULL, dPriv);
+
+ psp->DriverAPI.SwapBuffers(dPriv);
+
+ driReportDamage(dPriv, dPriv->pClipRects, dPriv->numClipRects);
+}
+
+static int driDrawableGetMSC( __DRIscreen *sPriv, __DRIdrawable *dPriv,
+ int64_t *msc )
+{
+ return sPriv->DriverAPI.GetDrawableMSC(sPriv, dPriv, msc);
+}
+
+
+static int driWaitForMSC(__DRIdrawable *dPriv, int64_t target_msc,
+ int64_t divisor, int64_t remainder,
+ int64_t * msc, int64_t * sbc)
+{
+ __DRIswapInfo sInfo;
+ int status;
+
+ status = dPriv->driScreenPriv->DriverAPI.WaitForMSC( dPriv, target_msc,
+ divisor, remainder,
+ msc );
+
+ /* GetSwapInfo() may not be provided by the driver if GLX_SGI_video_sync
+ * is supported but GLX_OML_sync_control is not. Therefore, don't return
+ * an error value if GetSwapInfo() is not implemented.
+ */
+ if ( status == 0
+ && dPriv->driScreenPriv->DriverAPI.GetSwapInfo ) {
+ status = dPriv->driScreenPriv->DriverAPI.GetSwapInfo( dPriv, & sInfo );
+ *sbc = sInfo.swap_count;
+ }
+
+ return status;
+}
+
+
+const __DRImediaStreamCounterExtension driMediaStreamCounterExtension = {
+ { __DRI_MEDIA_STREAM_COUNTER, __DRI_MEDIA_STREAM_COUNTER_VERSION },
+ driWaitForMSC,
+ driDrawableGetMSC,
+};
+
+
+static void driCopySubBuffer(__DRIdrawable *dPriv,
+ int x, int y, int w, int h)
+{
+ drm_clip_rect_t rect;
+
+ rect.x1 = x;
+ rect.y1 = dPriv->h - y - h;
+ rect.x2 = x + w;
+ rect.y2 = rect.y1 + h;
+ driReportDamage(dPriv, &rect, 1);
+
+ dPriv->driScreenPriv->DriverAPI.CopySubBuffer(dPriv, x, y, w, h);
+}
+
+const __DRIcopySubBufferExtension driCopySubBufferExtension = {
+ { __DRI_COPY_SUB_BUFFER, __DRI_COPY_SUB_BUFFER_VERSION },
+ driCopySubBuffer
+};
+
+static void driSetSwapInterval(__DRIdrawable *dPriv, unsigned int interval)
+{
+ dPriv->swap_interval = interval;
+}
+
+static unsigned int driGetSwapInterval(__DRIdrawable *dPriv)
+{
+ return dPriv->swap_interval;
+}
+
+const __DRIswapControlExtension driSwapControlExtension = {
+ { __DRI_SWAP_CONTROL, __DRI_SWAP_CONTROL_VERSION },
+ driSetSwapInterval,
+ driGetSwapInterval
+};
+
+
+/**
+ * This is called via __DRIscreenRec's createNewDrawable pointer.
+ */
+static __DRIdrawable *
+driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config,
+ drm_drawable_t hwDrawable, int renderType,
+ const int *attrs, void *data)
+{
+ __DRIdrawable *pdp;
+
+ /* Since pbuffers are not yet supported, no drawable attributes are
+ * supported either.
+ */
+ (void) attrs;
+
+ pdp = _mesa_malloc(sizeof *pdp);
+ if (!pdp) {
+ return NULL;
+ }
+
+ pdp->loaderPrivate = data;
+ pdp->hHWDrawable = hwDrawable;
+ pdp->refcount = 0;
+ pdp->pStamp = NULL;
+ pdp->lastStamp = 0;
+ pdp->index = 0;
+ pdp->x = 0;
+ pdp->y = 0;
+ pdp->w = 0;
+ pdp->h = 0;
+ pdp->numClipRects = 0;
+ pdp->numBackClipRects = 0;
+ pdp->pClipRects = NULL;
+ pdp->pBackClipRects = NULL;
+ pdp->vblSeq = 0;
+ pdp->vblFlags = 0;
+
+ pdp->driScreenPriv = psp;
+ pdp->driContextPriv = &psp->dummyContextPriv;
+
+ if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, &config->modes,
+ renderType == GLX_PIXMAP_BIT)) {
+ _mesa_free(pdp);
+ return NULL;
+ }
+
+ pdp->msc_base = 0;
+
+ /* This special default value is replaced with the configured
+ * default value when the drawable is first bound to a direct
+ * rendering context.
+ */
+ pdp->swap_interval = (unsigned)-1;
+
+ return pdp;
+}
+
+
+static __DRIdrawable *
+dri2CreateNewDrawable(__DRIscreen *screen, const __DRIconfig *config,
+ unsigned int drawable_id, unsigned int head, void *data)
+{
+ __DRIdrawable *pdraw;
+
+ pdraw = driCreateNewDrawable(screen, config, 0, 0, NULL, data);
+ if (!pdraw)
+ return NULL;
+
+ pdraw->dri2.drawable_id = drawable_id;
+ pdraw->dri2.tail = head;
+ pdraw->pBackClipRects = _mesa_malloc(sizeof *pdraw->pBackClipRects);
+
+ return pdraw;
+}
+
+
+static void
+driDestroyDrawable(__DRIdrawable *pdp)
+{
+ __DRIscreenPrivate *psp;
+
+ if (pdp) {
+ psp = pdp->driScreenPriv;
+ (*psp->DriverAPI.DestroyBuffer)(pdp);
+ if (pdp->pClipRects) {
+ _mesa_free(pdp->pClipRects);
+ pdp->pClipRects = NULL;
+ }
+ if (pdp->pBackClipRects) {
+ _mesa_free(pdp->pBackClipRects);
+ pdp->pBackClipRects = NULL;
+ }
+ _mesa_free(pdp);
+ }
+}
+
+/*@}*/
+
+
+/*****************************************************************/
+/** \name Context handling functions */
+/*****************************************************************/
+/*@{*/
+
+/**
+ * Destroy the per-context private information.
+ *
+ * \internal
+ * This function calls __DriverAPIRec::DestroyContext on \p contextPrivate, calls
+ * drmDestroyContext(), and finally frees \p contextPrivate.
+ */
+static void
+driDestroyContext(__DRIcontext *pcp)
+{
+ if (pcp) {
+ (*pcp->driScreenPriv->DriverAPI.DestroyContext)(pcp);
+ _mesa_free(pcp);
+ }
+}
+
+
+/**
+ * Create the per-drawable private driver information.
+ *
+ * \param render_type Type of rendering target. \c GLX_RGBA is the only
+ * type likely to ever be supported for direct-rendering.
+ * \param shared Context with which to share textures, etc. or NULL
+ *
+ * \returns An opaque pointer to the per-context private information on
+ * success, or \c NULL on failure.
+ *
+ * \internal
+ * This function allocates and fills a __DRIcontextPrivateRec structure. It
+ * performs some device independent initialization and passes all the
+ * relevant information to __DriverAPIRec::CreateContext to create the
+ * context.
+ *
+ */
+static __DRIcontext *
+driCreateNewContext(__DRIscreen *psp, const __DRIconfig *config,
+ int render_type, __DRIcontext *shared,
+ drm_context_t hwContext, void *data)
+{
+ __DRIcontext *pcp;
+ void * const shareCtx = (shared != NULL) ? shared->driverPrivate : NULL;
+
+ pcp = _mesa_malloc(sizeof *pcp);
+ if (!pcp)
+ return NULL;
+
+ pcp->driScreenPriv = psp;
+ pcp->driDrawablePriv = NULL;
+
+ /* When the first context is created for a screen, initialize a "dummy"
+ * context.
+ */
+
+ if (!psp->dri2.enabled && !psp->dummyContextPriv.driScreenPriv) {
+ psp->dummyContextPriv.hHWContext = psp->pSAREA->dummy_context;
+ psp->dummyContextPriv.driScreenPriv = psp;
+ psp->dummyContextPriv.driDrawablePriv = NULL;
+ psp->dummyContextPriv.driverPrivate = NULL;
+ /* No other fields should be used! */
+ }
+
+ pcp->hHWContext = hwContext;
+
+ if ( !(*psp->DriverAPI.CreateContext)(&config->modes, pcp, shareCtx) ) {
+ _mesa_free(pcp);
+ return NULL;
+ }
+
+ return pcp;
+}
+
+
+static __DRIcontext *
+dri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
+ __DRIcontext *shared, void *data)
+{
+ drm_context_t hwContext;
+ DRM_CAS_RESULT(ret);
+
+ /* DRI2 doesn't use kernel with context IDs, we just need an ID that's
+ * different from the kernel context ID to make drmLock() happy. */
+
+ do {
+ hwContext = screen->dri2.lock->next_id;
+ DRM_CAS(&screen->dri2.lock->next_id, hwContext, hwContext + 1, ret);
+ } while (ret);
+
+ return driCreateNewContext(screen, config, 0, shared, hwContext, data);
+}
+
+
+static int
+driCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask)
+{
+ return GL_FALSE;
+}
+
+/*@}*/
+
+
+/*****************************************************************/
+/** \name Screen handling functions */
+/*****************************************************************/
+/*@{*/
+
+/**
+ * Destroy the per-screen private information.
+ *
+ * \internal
+ * This function calls __DriverAPIRec::DestroyScreen on \p screenPrivate, calls
+ * drmClose(), and finally frees \p screenPrivate.
+ */
+static void driDestroyScreen(__DRIscreen *psp)
+{
+ if (psp) {
+ /* No interaction with the X-server is possible at this point. This
+ * routine is called after XCloseDisplay, so there is no protocol
+ * stream open to the X-server anymore.
+ */
+
+ if (psp->DriverAPI.DestroyScreen)
+ (*psp->DriverAPI.DestroyScreen)(psp);
+
+ if (psp->dri2.enabled) {
+#ifdef TTM_API
+ drmBOUnmap(psp->fd, &psp->dri2.sareaBO);
+ drmBOUnreference(psp->fd, &psp->dri2.sareaBO);
+#endif
+ } else {
+ (void)drmUnmap((drmAddress)psp->pSAREA, SAREA_MAX);
+ (void)drmUnmap((drmAddress)psp->pFB, psp->fbSize);
+ (void)drmCloseOnce(psp->fd);
+ }
+
+ _mesa_free(psp);
+ }
+}
+
+static void
+setupLoaderExtensions(__DRIscreen *psp,
+ const __DRIextension **extensions)
+{
+ int i;
+
+ for (i = 0; extensions[i]; i++) {
+ if (strcmp(extensions[i]->name, __DRI_GET_DRAWABLE_INFO) == 0)
+ psp->getDrawableInfo = (__DRIgetDrawableInfoExtension *) extensions[i];
+ if (strcmp(extensions[i]->name, __DRI_DAMAGE) == 0)
+ psp->damage = (__DRIdamageExtension *) extensions[i];
+ if (strcmp(extensions[i]->name, __DRI_SYSTEM_TIME) == 0)
+ psp->systemTime = (__DRIsystemTimeExtension *) extensions[i];
+ if (strcmp(extensions[i]->name, __DRI_LOADER) == 0)
+ psp->dri2.loader = (__DRIloaderExtension *) extensions[i];
+ }
+}
+
+/**
+ * This is the bootstrap function for the driver. libGL supplies all of the
+ * requisite information about the system, and the driver initializes itself.
+ * This routine also fills in the linked list pointed to by \c driver_modes
+ * with the \c __GLcontextModes that the driver can support for windows or
+ * pbuffers.
+ *
+ * For legacy DRI.
+ *
+ * \param scrn Index of the screen
+ * \param ddx_version Version of the 2D DDX. This may not be meaningful for
+ * all drivers.
+ * \param dri_version Version of the "server-side" DRI.
+ * \param drm_version Version of the kernel DRM.
+ * \param frame_buffer Data describing the location and layout of the
+ * framebuffer.
+ * \param pSAREA Pointer to the SAREA.
+ * \param fd Device handle for the DRM.
+ * \param extensions ??
+ * \param driver_modes Returns modes supported by the driver
+ * \param loaderPrivate ??
+ *
+ * \note There is no need to check the minimum API version in this
+ * function. Since the name of this function is versioned, it is
+ * impossible for a loader that is too old to even load this driver.
+ */
+static __DRIscreen *
+driCreateNewScreen(int scrn,
+ const __DRIversion *ddx_version,
+ const __DRIversion *dri_version,
+ const __DRIversion *drm_version,
+ const __DRIframebuffer *frame_buffer,
+ drmAddress pSAREA, int fd,
+ const __DRIextension **extensions,
+ const __DRIconfig ***driver_modes,
+ void *loaderPrivate)
+{
+ static const __DRIextension *emptyExtensionList[] = { NULL };
+ __DRIscreen *psp;
+
+ psp = _mesa_malloc(sizeof *psp);
+ if (!psp)
+ return NULL;
+
+ setupLoaderExtensions(psp, extensions);
+
+ /*
+ ** NOT_DONE: This is used by the X server to detect when the client
+ ** has died while holding the drawable lock. The client sets the
+ ** drawable lock to this value.
+ */
+ psp->drawLockID = 1;
+
+ psp->drm_version = *drm_version;
+ psp->ddx_version = *ddx_version;
+ psp->dri_version = *dri_version;
+
+ psp->pSAREA = pSAREA;
+ psp->lock = (drmLock *) &psp->pSAREA->lock;
+
+ psp->pFB = frame_buffer->base;
+ psp->fbSize = frame_buffer->size;
+ psp->fbStride = frame_buffer->stride;
+ psp->fbWidth = frame_buffer->width;
+ psp->fbHeight = frame_buffer->height;
+ psp->devPrivSize = frame_buffer->dev_priv_size;
+ psp->pDevPriv = frame_buffer->dev_priv;
+ psp->fbBPP = psp->fbStride * 8 / frame_buffer->width;
+
+ psp->extensions = emptyExtensionList;
+ psp->fd = fd;
+ psp->myNum = scrn;
+ psp->dri2.enabled = GL_FALSE;
+
+ /*
+ ** Do not init dummy context here; actual initialization will be
+ ** done when the first DRI context is created. Init screen priv ptr
+ ** to NULL to let CreateContext routine that it needs to be inited.
+ */
+ psp->dummyContextPriv.driScreenPriv = NULL;
+
+ psp->DriverAPI = driDriverAPI;
+
+ *driver_modes = driDriverAPI.InitScreen(psp);
+ if (*driver_modes == NULL) {
+ _mesa_free(psp);
+ return NULL;
+ }
+
+ return psp;
+}
+
+
+/**
+ * DRI2
+ */
+static __DRIscreen *
+dri2CreateNewScreen(int scrn, int fd, unsigned int sarea_handle,
+ const __DRIextension **extensions,
+ const __DRIconfig ***driver_configs, void *data)
+{
+#ifdef TTM_API
+ static const __DRIextension *emptyExtensionList[] = { NULL };
+ __DRIscreen *psp;
+ unsigned int *p;
+ drmVersionPtr version;
+
+ if (driDriverAPI.InitScreen2 == NULL)
+ return NULL;
+
+ psp = _mesa_malloc(sizeof(*psp));
+ if (!psp)
+ return NULL;
+
+ setupLoaderExtensions(psp, extensions);
+
+ version = drmGetVersion(fd);
+ if (version) {
+ psp->drm_version.major = version->version_major;
+ psp->drm_version.minor = version->version_minor;
+ psp->drm_version.patch = version->version_patchlevel;
+ drmFreeVersion(version);
+ }
+
+ psp->extensions = emptyExtensionList;
+ psp->fd = fd;
+ psp->myNum = scrn;
+ psp->dri2.enabled = GL_TRUE;
+
+ if (drmBOReference(psp->fd, sarea_handle, &psp->dri2.sareaBO)) {
+ fprintf(stderr, "Failed to reference DRI2 sarea BO\n");
+ _mesa_free(psp);
+ return NULL;
+ }
+
+ if (drmBOMap(psp->fd, &psp->dri2.sareaBO,
+ DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, &psp->dri2.sarea)) {
+ drmBOUnreference(psp->fd, &psp->dri2.sareaBO);
+ _mesa_free(psp);
+ return NULL;
+ }
+
+ p = psp->dri2.sarea;
+ while (DRI2_SAREA_BLOCK_TYPE(*p)) {
+ switch (DRI2_SAREA_BLOCK_TYPE(*p)) {
+ case DRI2_SAREA_BLOCK_LOCK:
+ psp->dri2.lock = (__DRILock *) p;
+ break;
+ case DRI2_SAREA_BLOCK_EVENT_BUFFER:
+ psp->dri2.buffer = (__DRIEventBuffer *) p;
+ break;
+ }
+ p = DRI2_SAREA_BLOCK_NEXT(p);
+ }
+
+ psp->lock = (drmLock *) &psp->dri2.lock->lock;
+
+ psp->DriverAPI = driDriverAPI;
+ *driver_configs = driDriverAPI.InitScreen2(psp);
+ if (*driver_configs == NULL) {
+ drmBOUnmap(psp->fd, &psp->dri2.sareaBO);
+ drmBOUnreference(psp->fd, &psp->dri2.sareaBO);
+ _mesa_free(psp);
+ return NULL;
+ }
+
+ psp->DriverAPI = driDriverAPI;
+
+ return psp;
+#else
+ return NULL;
+#endif
+}
+
+static const __DRIextension **driGetExtensions(__DRIscreen *psp)
+{
+ return psp->extensions;
+}
+
+/** Legacy DRI interface */
+const __DRIlegacyExtension driLegacyExtension = {
+ { __DRI_LEGACY, __DRI_LEGACY_VERSION },
+ driCreateNewScreen,
+ driCreateNewDrawable,
+ driCreateNewContext
+};
+
+/** DRI2 interface */
+const __DRIcoreExtension driCoreExtension = {
+ { __DRI_CORE, __DRI_CORE_VERSION },
+ dri2CreateNewScreen,
+ driDestroyScreen,
+ driGetExtensions,
+ driGetConfigAttrib,
+ driIndexConfigAttrib,
+ dri2CreateNewDrawable,
+ driDestroyDrawable,
+ driSwapBuffers,
+ dri2CreateNewContext,
+ driCopyContext,
+ driDestroyContext,
+ driBindContext,
+ driUnbindContext
+};
+
+/* This is the table of extensions that the loader will dlsym() for. */
+PUBLIC const __DRIextension *__driDriverExtensions[] = {
+ &driCoreExtension.base,
+ &driLegacyExtension.base,
+ NULL
+};
+
+static int
+driFrameTracking(__DRIdrawable *drawable, GLboolean enable)
+{
+ return GLX_BAD_CONTEXT;
+}
+
+static int
+driQueryFrameTracking(__DRIdrawable *dpriv,
+ int64_t * sbc, int64_t * missedFrames,
+ float * lastMissedUsage, float * usage)
+{
+ __DRIswapInfo sInfo;
+ int status;
+ int64_t ust;
+ __DRIscreenPrivate *psp = dpriv->driScreenPriv;
+
+ status = dpriv->driScreenPriv->DriverAPI.GetSwapInfo( dpriv, & sInfo );
+ if ( status == 0 ) {
+ *sbc = sInfo.swap_count;
+ *missedFrames = sInfo.swap_missed_count;
+ *lastMissedUsage = sInfo.swap_missed_usage;
+
+ (*psp->systemTime->getUST)( & ust );
+ *usage = driCalculateSwapUsage( dpriv, sInfo.swap_ust, ust );
+ }
+
+ return status;
+}
+
+const __DRIframeTrackingExtension driFrameTrackingExtension = {
+ { __DRI_FRAME_TRACKING, __DRI_FRAME_TRACKING_VERSION },
+ driFrameTracking,
+ driQueryFrameTracking
+};
+
+/**
+ * Calculate amount of swap interval used between GLX buffer swaps.
+ *
+ * The usage value, on the range [0,max], is the fraction of total swap
+ * interval time used between GLX buffer swaps is calculated.
+ *
+ * \f$p = t_d / (i * t_r)\f$
+ *
+ * Where \f$t_d\f$ is the time since the last GLX buffer swap, \f$i\f$ is the
+ * swap interval (as set by \c glXSwapIntervalSGI), and \f$t_r\f$ time
+ * required for a single vertical refresh period (as returned by \c
+ * glXGetMscRateOML).
+ *
+ * See the documentation for the GLX_MESA_swap_frame_usage extension for more
+ * details.
+ *
+ * \param dPriv Pointer to the private drawable structure.
+ * \return If less than a single swap interval time period was required
+ * between GLX buffer swaps, a number greater than 0 and less than
+ * 1.0 is returned. If exactly one swap interval time period is
+ * required, 1.0 is returned, and if more than one is required then
+ * a number greater than 1.0 will be returned.
+ *
+ * \sa glXSwapIntervalSGI glXGetMscRateOML
+ *
+ * \todo Instead of caching the \c glXGetMscRateOML function pointer, would it
+ * be possible to cache the sync rate?
+ */
+float
+driCalculateSwapUsage( __DRIdrawablePrivate *dPriv, int64_t last_swap_ust,
+ int64_t current_ust )
+{
+ int32_t n;
+ int32_t d;
+ int interval;
+ float usage = 1.0;
+ __DRIscreenPrivate *psp = dPriv->driScreenPriv;
+
+ if ( (*psp->systemTime->getMSCRate)(dPriv, &n, &d, dPriv->loaderPrivate) ) {
+ interval = (dPriv->swap_interval != 0) ? dPriv->swap_interval : 1;
+
+
+ /* We want to calculate
+ * (current_UST - last_swap_UST) / (interval * us_per_refresh). We get
+ * current_UST by calling __glXGetUST. last_swap_UST is stored in
+ * dPriv->swap_ust. interval has already been calculated.
+ *
+ * The only tricky part is us_per_refresh. us_per_refresh is
+ * 1000000 / MSC_rate. We know the MSC_rate is n / d. We can flip it
+ * around and say us_per_refresh = 1000000 * d / n. Since this goes in
+ * the denominator of the final calculation, we calculate
+ * (interval * 1000000 * d) and move n into the numerator.
+ */
+
+ usage = (current_ust - last_swap_ust);
+ usage *= n;
+ usage /= (interval * d);
+ usage /= 1000000.0;
+ }
+
+ return usage;
+}
+
+/*@}*/
diff --git a/src/VBox/Additions/common/crOpenGL/drirenderbuffer.c b/src/VBox/Additions/common/crOpenGL/drirenderbuffer.c
new file mode 100644
index 00000000..d36af3e5
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/drirenderbuffer.c
@@ -0,0 +1,215 @@
+
+#include "mtypes.h"
+#include "drirenderbuffer.h"
+#include "framebuffer.h"
+#include "renderbuffer.h"
+#include "imports.h"
+
+
+/**
+ * This will get called when a window (gl_framebuffer) is resized (probably
+ * via driUpdateFramebufferSize(), below).
+ * Just update width, height and internal format fields for now.
+ * There's usually no memory allocation above because the present
+ * DRI drivers use statically-allocated full-screen buffers. If that's not
+ * the case for a DRI driver, a different AllocStorage method should
+ * be used.
+ */
+static GLboolean
+driRenderbufferStorage(GLcontext *ctx, struct gl_renderbuffer *rb,
+ GLenum internalFormat, GLuint width, GLuint height)
+{
+ rb->Width = width;
+ rb->Height = height;
+ rb->InternalFormat = internalFormat;
+ return GL_TRUE;
+}
+
+
+static void
+driDeleteRenderbuffer(struct gl_renderbuffer *rb)
+{
+ /* don't free rb->Data Chances are it's a memory mapped region for
+ * the dri drivers.
+ */
+ _mesa_free(rb);
+}
+
+
+/**
+ * Allocate a new driRenderbuffer object.
+ * Individual drivers are free to implement different versions of
+ * this function.
+ *
+ * At this time, this function can only be used for window-system
+ * renderbuffers, not user-created RBOs.
+ *
+ * \param format Either GL_RGBA, GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT24,
+ * GL_DEPTH_COMPONENT32, or GL_STENCIL_INDEX8_EXT (for now).
+ * \param addr address in main memory of the buffer. Probably a memory
+ * mapped region.
+ * \param cpp chars or bytes per pixel
+ * \param offset start of renderbuffer with respect to start of framebuffer
+ * \param pitch pixels per row
+ */
+driRenderbuffer *
+driNewRenderbuffer(GLenum format, GLvoid *addr,
+ GLint cpp, GLint offset, GLint pitch,
+ __DRIdrawablePrivate *dPriv)
+{
+ driRenderbuffer *drb;
+
+ assert(format == GL_RGBA ||
+ format == GL_RGB5 ||
+ format == GL_RGBA8 ||
+ format == GL_DEPTH_COMPONENT16 ||
+ format == GL_DEPTH_COMPONENT24 ||
+ format == GL_DEPTH_COMPONENT32 ||
+ format == GL_STENCIL_INDEX8_EXT);
+
+ assert(cpp > 0);
+ assert(pitch > 0);
+
+ drb = _mesa_calloc(sizeof(driRenderbuffer));
+ if (drb) {
+ const GLuint name = 0;
+
+ _mesa_init_renderbuffer(&drb->Base, name);
+
+ /* Make sure we're using a null-valued GetPointer routine */
+ assert(drb->Base.GetPointer(NULL, &drb->Base, 0, 0) == NULL);
+
+ drb->Base.InternalFormat = format;
+
+ if (format == GL_RGBA || format == GL_RGB5 || format == GL_RGBA8) {
+ /* Color */
+ drb->Base._BaseFormat = GL_RGBA;
+ drb->Base.DataType = GL_UNSIGNED_BYTE;
+ if (format == GL_RGB5) {
+ drb->Base.RedBits = 5;
+ drb->Base.GreenBits = 6;
+ drb->Base.BlueBits = 5;
+ }
+ else {
+ drb->Base.RedBits =
+ drb->Base.GreenBits =
+ drb->Base.BlueBits =
+ drb->Base.AlphaBits = 8;
+ }
+ }
+ else if (format == GL_DEPTH_COMPONENT16) {
+ /* Depth */
+ drb->Base._BaseFormat = GL_DEPTH_COMPONENT;
+ /* we always Get/Put 32-bit Z values */
+ drb->Base.DataType = GL_UNSIGNED_INT;
+ drb->Base.DepthBits = 16;
+ }
+ else if (format == GL_DEPTH_COMPONENT24) {
+ /* Depth */
+ drb->Base._BaseFormat = GL_DEPTH_COMPONENT;
+ /* we always Get/Put 32-bit Z values */
+ drb->Base.DataType = GL_UNSIGNED_INT;
+ drb->Base.DepthBits = 24;
+ }
+ else if (format == GL_DEPTH_COMPONENT32) {
+ /* Depth */
+ drb->Base._BaseFormat = GL_DEPTH_COMPONENT;
+ /* we always Get/Put 32-bit Z values */
+ drb->Base.DataType = GL_UNSIGNED_INT;
+ drb->Base.DepthBits = 32;
+ }
+ else {
+ /* Stencil */
+ ASSERT(format == GL_STENCIL_INDEX8_EXT);
+ drb->Base._BaseFormat = GL_STENCIL_INDEX;
+ drb->Base.DataType = GL_UNSIGNED_BYTE;
+ drb->Base.StencilBits = 8;
+ }
+
+ /* XXX if we were allocating a user-created renderbuffer, we'd have
+ * to fill in the Red/Green/Blue/.../Bits values too.
+ */
+
+ drb->Base.AllocStorage = driRenderbufferStorage;
+ drb->Base.Delete = driDeleteRenderbuffer;
+
+ drb->Base.Data = addr;
+
+ /* DRI renderbuffer-specific fields: */
+ drb->dPriv = dPriv;
+ drb->offset = offset;
+ drb->pitch = pitch;
+ drb->cpp = cpp;
+
+ /* may be changed if page flipping is active: */
+ drb->flippedOffset = offset;
+ drb->flippedPitch = pitch;
+ drb->flippedData = addr;
+ }
+ return drb;
+}
+
+
+/**
+ * Update the front and back renderbuffers' flippedPitch/Offset/Data fields.
+ * If stereo, flip both the left and right pairs.
+ * This is used when we do double buffering via page flipping.
+ * \param fb the framebuffer we're page flipping
+ * \param flipped if true, set flipped values, else set non-flipped values
+ */
+void
+driFlipRenderbuffers(struct gl_framebuffer *fb, GLboolean flipped)
+{
+ const GLuint count = fb->Visual.stereoMode ? 2 : 1;
+ GLuint lr; /* left or right */
+
+ /* we shouldn't really call this function if single-buffered, but
+ * play it safe.
+ */
+ if (!fb->Visual.doubleBufferMode)
+ return;
+
+ for (lr = 0; lr < count; lr++) {
+ GLuint frontBuf = (lr == 0) ? BUFFER_FRONT_LEFT : BUFFER_FRONT_RIGHT;
+ GLuint backBuf = (lr == 0) ? BUFFER_BACK_LEFT : BUFFER_BACK_RIGHT;
+ driRenderbuffer *front_drb
+ = (driRenderbuffer *) fb->Attachment[frontBuf].Renderbuffer;
+ driRenderbuffer *back_drb
+ = (driRenderbuffer *) fb->Attachment[backBuf].Renderbuffer;
+
+ if (flipped) {
+ front_drb->flippedOffset = back_drb->offset;
+ front_drb->flippedPitch = back_drb->pitch;
+ front_drb->flippedData = back_drb->Base.Data;
+ back_drb->flippedOffset = front_drb->offset;
+ back_drb->flippedPitch = front_drb->pitch;
+ back_drb->flippedData = front_drb->Base.Data;
+ }
+ else {
+ front_drb->flippedOffset = front_drb->offset;
+ front_drb->flippedPitch = front_drb->pitch;
+ front_drb->flippedData = front_drb->Base.Data;
+ back_drb->flippedOffset = back_drb->offset;
+ back_drb->flippedPitch = back_drb->pitch;
+ back_drb->flippedData = back_drb->Base.Data;
+ }
+ }
+}
+
+
+/**
+ * Check that the gl_framebuffer associated with dPriv is the right size.
+ * Resize the gl_framebuffer if needed.
+ * It's expected that the dPriv->driverPrivate member points to a
+ * gl_framebuffer object.
+ */
+void
+driUpdateFramebufferSize(GLcontext *ctx, const __DRIdrawablePrivate *dPriv)
+{
+ struct gl_framebuffer *fb = (struct gl_framebuffer *) dPriv->driverPrivate;
+ if (fb && (dPriv->w != fb->Width || dPriv->h != fb->Height)) {
+ ctx->Driver.ResizeBuffers(ctx, fb, dPriv->w, dPriv->h);
+ assert(fb->Width == dPriv->w);
+ assert(fb->Height == dPriv->h);
+ }
+}
diff --git a/src/VBox/Additions/common/crOpenGL/egl.c b/src/VBox/Additions/common/crOpenGL/egl.c
new file mode 100644
index 00000000..3d8a636d
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/egl.c
@@ -0,0 +1,967 @@
+/* $Id: egl.c $ */
+
+/** @file
+ * VBox OpenGL EGL implentation.
+ */
+
+/*
+ * Copyright (C) 2009-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+
+/*********************************************************************************************************************************
+* Header Files *
+*********************************************************************************************************************************/
+#include <iprt/cdefs.h>
+#include <iprt/types.h>
+
+#include <EGL/egl.h>
+#include <GL/glx.h>
+#include <X11/Xlib.h>
+
+#include <dlfcn.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define EGL_ASSERT(expr) \
+ if (!(expr)) { printf("Assertion failed: %s\n", #expr); exit(1); }
+
+
+/*********************************************************************************************************************************
+* Structures and Typedefs *
+*********************************************************************************************************************************/
+
+struct VBEGLTLS
+{
+ /** The last EGL error. */
+ EGLint cErr;
+ /** The EGL API currently bound to this thread. */
+ EGLenum enmAPI;
+ /** The current context. */
+ EGLContext hCurrent;
+ /** The display bound to the current context. */
+ EGLDisplay hCurrentDisplay;
+ /** The draw surface bound to the current context. */
+ EGLSurface hCurrentDraw;
+ /** The read surface bound to the current context. */
+ EGLSurface hCurrentRead;
+};
+
+
+/*********************************************************************************************************************************
+* Defined Constants And Macros *
+*********************************************************************************************************************************/
+/** @note IDs returned for surfaces should always be lower than these constants.
+ */
+/** This is OR-ed with a surface ID to mark it as a window, as GLX needs to
+ * know. */
+#define VBEGL_WINDOW_SURFACE 0x20000000
+/** This is OR-ed with a surface ID to mark it as a pbuffer, as GLX needs to
+ * know. */
+#define VBEGL_PBUFFER_SURFACE 0x40000000
+/** This is OR-ed with a surface ID to mark it as a pixmap, as GLX needs to
+ * know. */
+#define VBEGL_PIXMAP_SURFACE 0x80000000
+#define VBEGL_ANY_SURFACE (VBEGL_WINDOW_SURFACE | VBEGL_PBUFFER_SURFACE | VBEGL_PIXMAP_SURFACE)
+
+
+/*********************************************************************************************************************************
+* Global variables *
+*********************************************************************************************************************************/
+
+static pthread_key_t g_tls;
+static pthread_once_t g_tlsOnce = PTHREAD_ONCE_INIT;
+static Display *g_pDefaultDisplay = NULL;
+static pthread_once_t g_defaultDisplayOnce = PTHREAD_ONCE_INIT;
+
+static void tlsInitOnce(void)
+{
+ pthread_key_create(&g_tls, NULL);
+}
+
+static struct VBEGLTLS *getTls(void)
+{
+ struct VBEGLTLS *pTls;
+
+ pthread_once(&g_tlsOnce, tlsInitOnce);
+ pTls = (struct VBEGLTLS *)pthread_getspecific(g_tls);
+ if (RT_LIKELY(pTls))
+ return pTls;
+ pTls = (struct VBEGLTLS *)malloc(sizeof(*pTls));
+ if (!pTls)
+ return NULL;
+ pTls->cErr = EGL_SUCCESS;
+ pTls->enmAPI = EGL_NONE;
+ pTls->hCurrent = EGL_NO_CONTEXT;
+ pTls->hCurrentDisplay = EGL_NO_DISPLAY;
+ pTls->hCurrentDraw = EGL_NO_SURFACE;
+ pTls->hCurrentRead = EGL_NO_SURFACE;
+ if (pthread_setspecific(g_tls, pTls) == 0)
+ return pTls;
+ free(pTls);
+ return NULL;
+}
+
+static void defaultDisplayInitOnce(void)
+{
+ g_pDefaultDisplay = XOpenDisplay(NULL);
+}
+
+static EGLBoolean clearEGLError(void)
+{
+ struct VBEGLTLS *pTls = getTls();
+
+ if (!VALID_PTR(pTls))
+ return EGL_FALSE;
+ pTls->cErr = EGL_SUCCESS;
+ return EGL_TRUE;
+}
+
+static EGLBoolean setEGLError(EGLint cErr)
+{
+ struct VBEGLTLS *pTls = getTls();
+
+ if (pTls)
+ pTls->cErr = cErr;
+ return EGL_FALSE;
+}
+
+static EGLBoolean testValidDisplay(EGLNativeDisplayType hDisplay)
+{
+ void *pSymbol = dlsym(NULL, "gbm_create_device");
+
+ if (hDisplay == EGL_DEFAULT_DISPLAY)
+ return EGL_TRUE;
+ if ((void *)hDisplay == NULL)
+ return EGL_FALSE;
+ /* This is the test that Mesa uses to see if this is a GBM "display". Not
+ * very pretty, but since no one can afford to break Mesa it should be
+ * safe. We need this to detect when the X server tries to load us. */
+ if (pSymbol != NULL && *(void **)hDisplay == pSymbol)
+ return EGL_FALSE;
+ return EGL_TRUE;
+}
+
+DECLEXPORT(EGLDisplay) eglGetDisplay(EGLNativeDisplayType hDisplay)
+{
+ Display *pDisplay;
+
+ if (!testValidDisplay(hDisplay))
+ return EGL_NO_DISPLAY;
+ if (!clearEGLError()) /* Set up our tls. */
+ return EGL_NO_DISPLAY;
+ if (hDisplay != EGL_DEFAULT_DISPLAY)
+ pDisplay = hDisplay;
+ else
+ {
+ pthread_once(&g_defaultDisplayOnce, defaultDisplayInitOnce);
+ pDisplay = g_pDefaultDisplay;
+ }
+ if (pDisplay && !strcmp(glXGetClientString(pDisplay, GLX_VENDOR), "Chromium"))
+ return (EGLDisplay) pDisplay;
+ return EGL_NO_DISPLAY;
+}
+
+DECLEXPORT(EGLint) eglGetError(void)
+{
+ struct VBEGLTLS *pTls = getTls();
+
+ if (pTls)
+ return pTls->cErr;
+ return EGL_NOT_INITIALIZED;
+}
+
+DECLEXPORT(EGLBoolean) eglInitialize (EGLDisplay hDisplay, EGLint *pcMajor, EGLint *pcMinor)
+{
+ if (hDisplay == EGL_NO_DISPLAY)
+ return EGL_FALSE;
+ if (!VALID_PTR(hDisplay))
+ return setEGLError(EGL_BAD_DISPLAY);
+ if (pcMajor)
+ *pcMajor = 1;
+ if (pcMinor)
+ *pcMinor = 4;
+ return clearEGLError();
+}
+
+/** @todo This function should terminate all allocated resources. */
+DECLEXPORT(EGLBoolean) eglTerminate(EGLDisplay hDisplay)
+{
+ if (!VALID_PTR(hDisplay))
+ return EGL_FALSE;
+ return EGL_TRUE;
+}
+
+DECLEXPORT(const char *) eglQueryString(EGLDisplay hDisplay, EGLint name)
+{
+ RT_NOREF(hDisplay);
+ switch (name)
+ {
+ case EGL_CLIENT_APIS:
+ return "OpenGL";
+ case EGL_VENDOR:
+ return "Chromium";
+ case EGL_VERSION:
+ return "1.4 Chromium";
+ case EGL_EXTENSIONS:
+ return "";
+ default:
+ return NULL;
+ }
+}
+
+DECLEXPORT(EGLBoolean) eglGetConfigs (EGLDisplay hDisplay, EGLConfig *paConfigs, EGLint caConfigs, EGLint *pcaConfigs)
+{
+ Display *pDisplay = (Display *)hDisplay;
+ GLXFBConfig *paFBConfigs;
+ int caFBConfigs, i;
+
+ if (!VALID_PTR(pDisplay))
+ return setEGLError(EGL_NOT_INITIALIZED);
+ if (!VALID_PTR(pcaConfigs))
+ return setEGLError(EGL_BAD_PARAMETER);
+ if (caConfigs > 0 && !VALID_PTR(paConfigs))
+ return setEGLError(EGL_BAD_PARAMETER);
+ paFBConfigs = glXGetFBConfigs(pDisplay, DefaultScreen(pDisplay), &caFBConfigs);
+ if (!VALID_PTR(paFBConfigs))
+ return setEGLError(EGL_BAD_PARAMETER);
+ if (caFBConfigs > caConfigs)
+ caFBConfigs = caConfigs;
+ *pcaConfigs = caFBConfigs;
+ for (i = 0; i < caFBConfigs; ++i)
+ paConfigs[i] = (EGLConfig)paFBConfigs[i];
+ XFree(paFBConfigs);
+ return clearEGLError();
+}
+
+static int convertEGLAttribToGLX(EGLint a_EGLAttrib)
+{
+ switch (a_EGLAttrib)
+ {
+ case EGL_BUFFER_SIZE:
+ return GLX_BUFFER_SIZE;
+ case EGL_RED_SIZE:
+ return GLX_RED_SIZE;
+ case EGL_GREEN_SIZE:
+ return GLX_GREEN_SIZE;
+ case EGL_BLUE_SIZE:
+ return GLX_BLUE_SIZE;
+ case EGL_LUMINANCE_SIZE:
+ return GLX_RED_SIZE;
+ case EGL_ALPHA_SIZE:
+ return GLX_ALPHA_SIZE;
+ /* case EGL_ALPHA_MASK_SIZE: */
+ /* case EGL_BIND_TO_TEXTURE_RGB: */
+ /* case EGL_BIND_TO_TEXTURE_RGBA: */
+ /* case EGL_COLOR_BUFFER_TYPE: */
+ /* case EGL_CONFIG_CAVEAT: */
+ case EGL_CONFIG_ID:
+ return GLX_FBCONFIG_ID;
+ /* case EGL_CONFORMANT: */
+ case EGL_DEPTH_SIZE:
+ return GLX_DEPTH_SIZE;
+ case EGL_LEVEL:
+ return GLX_LEVEL;
+ case EGL_MAX_PBUFFER_WIDTH:
+ return GLX_MAX_PBUFFER_WIDTH;
+ case EGL_MAX_PBUFFER_HEIGHT:
+ return GLX_MAX_PBUFFER_HEIGHT;
+ case EGL_MAX_PBUFFER_PIXELS:
+ return GLX_MAX_PBUFFER_PIXELS;
+ /* case EGL_MATCH_NATIVE_PIXMAP: */
+ /* case EGL_MAX_SWAP_INTERVAL: */
+ /* case EGL_MIN_SWAP_INTERVAL: */
+ case EGL_NATIVE_RENDERABLE:
+ return GLX_X_RENDERABLE;
+ case EGL_NATIVE_VISUAL_ID:
+ return GLX_VISUAL_ID;
+ /* case EGL_NATIVE_VISUAL_TYPE: */
+ /* case EGL_RENDERABLE_TYPE: */
+ case EGL_SAMPLE_BUFFERS:
+ return GLX_SAMPLE_BUFFERS;
+ case EGL_SAMPLES:
+ return GLX_SAMPLES;
+ case EGL_STENCIL_SIZE:
+ return GLX_STENCIL_SIZE;
+ /* case EGL_SURFACE_TYPE: */
+ /* case EGL_TRANSPARENT_TYPE: */
+ case EGL_TRANSPARENT_RED_VALUE:
+ return GLX_TRANSPARENT_RED_VALUE;
+ case EGL_TRANSPARENT_GREEN_VALUE:
+ return GLX_TRANSPARENT_GREEN_VALUE;
+ case EGL_TRANSPARENT_BLUE_VALUE:
+ return GLX_TRANSPARENT_BLUE_VALUE;
+ default:
+ return None;
+ }
+}
+
+DECLEXPORT(EGLBoolean) eglChooseConfig (EGLDisplay hDisplay, const EGLint *paAttribs, EGLConfig *paConfigs, EGLint caConfigs,
+ EGLint *pcConfigs)
+{
+ Display *pDisplay = (Display *)hDisplay;
+ int aAttribList[256]; /* The list cannot be this long. */
+ unsigned cAttribs = 0, i;
+ const EGLint *pAttrib, *pAttrib2;
+ EGLint cRenderableType = EGL_OPENGL_ES_BIT;
+ unsigned cConfigCaveat = GLX_DONT_CARE, cConformant = GLX_DONT_CARE;
+ GLXFBConfig *paFBConfigs;
+ int caFBConfigs;
+
+ if (!VALID_PTR(hDisplay))
+ return setEGLError(EGL_NOT_INITIALIZED);
+ if (!VALID_PTR(pcConfigs))
+ return setEGLError(EGL_BAD_PARAMETER);
+ if (caConfigs > 0 && !VALID_PTR(paConfigs))
+ return setEGLError(EGL_BAD_PARAMETER);
+ for (pAttrib = paAttribs; pAttrib != NULL && *pAttrib != EGL_NONE; pAttrib += 2)
+ {
+ bool fSkip = false;
+ int cGLXAttrib;
+
+ /* Check for illegal values. */
+ if ((*pAttrib == EGL_LEVEL || *pAttrib == EGL_MATCH_NATIVE_PIXMAP) && pAttrib[1] == EGL_DONT_CARE)
+ return setEGLError(EGL_BAD_ATTRIBUTE);
+ /* Check for values we can't handle. */
+ if ( (*pAttrib == EGL_ALPHA_MASK_SIZE)
+ && pAttrib[1] != EGL_DONT_CARE && pAttrib[1] != 0)
+ return setEGLError(EGL_BAD_ACCESS);
+ /** @todo try creating a pixmap from a native one with the configurations returned. */
+ if (*pAttrib == EGL_MATCH_NATIVE_PIXMAP)
+ return setEGLError(EGL_BAD_ACCESS);
+ if ( ( *pAttrib == EGL_MIN_SWAP_INTERVAL || *pAttrib == EGL_MAX_SWAP_INTERVAL
+ || *pAttrib == EGL_BIND_TO_TEXTURE_RGB || *pAttrib == EGL_BIND_TO_TEXTURE_RGBA)
+ && pAttrib[1] != EGL_DONT_CARE)
+ return setEGLError(EGL_BAD_ACCESS);
+ /* Ignore attributes which are repeated later. */
+ for (pAttrib2 = pAttrib + 2; *pAttrib2 != EGL_NONE; pAttrib2 += 2)
+ if (*pAttrib2 == *pAttrib)
+ {
+ fSkip = true;
+ break;
+ }
+
+ if (fSkip)
+ continue;
+ cGLXAttrib = convertEGLAttribToGLX(*pAttrib);
+ if (cGLXAttrib != None)
+ {
+ aAttribList[cAttribs] = cGLXAttrib;
+ if (pAttrib[1] == EGL_DONT_CARE)
+ aAttribList[cAttribs + 1] = GLX_DONT_CARE;
+ else
+ aAttribList[cAttribs + 1] = pAttrib[1];
+ cAttribs += 2;
+ }
+ else
+ {
+ switch (*pAttrib)
+ {
+ case EGL_COLOR_BUFFER_TYPE:
+ aAttribList[cAttribs] = GLX_X_VISUAL_TYPE;
+ aAttribList[cAttribs + 1] = pAttrib[1] == EGL_DONT_CARE ? GLX_DONT_CARE
+ : pAttrib[1] == EGL_RGB_BUFFER ? GLX_TRUE_COLOR
+ : pAttrib[1] == EGL_LUMINANCE_BUFFER ? GLX_GRAY_SCALE
+ : GL_FALSE;
+ if ( *pAttrib == EGL_COLOR_BUFFER_TYPE
+ && pAttrib[1] != EGL_DONT_CARE && pAttrib[1] != EGL_RGB_BUFFER)
+ return setEGLError(EGL_BAD_ACCESS);
+ break;
+ case EGL_CONFIG_CAVEAT:
+ cConfigCaveat = pAttrib[1] == EGL_DONT_CARE ? GLX_DONT_CARE
+ : pAttrib[1] == EGL_NONE ? GLX_NONE
+ : pAttrib[1] == EGL_SLOW_CONFIG ? GLX_SLOW_CONFIG
+ : pAttrib[1] == EGL_NON_CONFORMANT_CONFIG ? GLX_NON_CONFORMANT_CONFIG
+ : GL_FALSE;
+ if (!cConfigCaveat)
+ return setEGLError(EGL_BAD_ATTRIBUTE);
+ cAttribs -= 2;
+ break;
+ case EGL_CONFORMANT:
+ if (pAttrib[1] != EGL_OPENGL_BIT && pAttrib[1] != 0)
+ return setEGLError(EGL_BAD_ACCESS);
+ cConformant = pAttrib[1] == EGL_OPENGL_BIT ? GL_TRUE : GL_FALSE;
+ cAttribs -= 2;
+ break;
+ case EGL_NATIVE_VISUAL_TYPE:
+ aAttribList[cAttribs] = GLX_X_VISUAL_TYPE;
+ aAttribList[cAttribs + 1] = pAttrib[1] == EGL_DONT_CARE ? GLX_DONT_CARE
+ : pAttrib[1] == StaticGray ? GLX_STATIC_GRAY
+ : pAttrib[1] == StaticColor ? GLX_STATIC_COLOR
+ : pAttrib[1] == TrueColor ? GLX_TRUE_COLOR
+ : pAttrib[1] == GrayScale ? GLX_GRAY_SCALE
+ : pAttrib[1] == PseudoColor ? GLX_PSEUDO_COLOR
+ : pAttrib[1] == DirectColor ? GLX_DIRECT_COLOR
+ : GL_FALSE;
+ break;
+ case EGL_RENDERABLE_TYPE:
+ cRenderableType = pAttrib[1];
+ cAttribs -= 2; /* We did not add anything to the list. */
+ break;
+ case EGL_SURFACE_TYPE:
+ if (pAttrib[1] & ~(EGL_PBUFFER_BIT | EGL_PIXMAP_BIT | EGL_WINDOW_BIT))
+ return setEGLError(EGL_BAD_ACCESS);
+ aAttribList[cAttribs] = GLX_DRAWABLE_TYPE;
+ aAttribList[cAttribs + 1] = (pAttrib[1] & EGL_PBUFFER_BIT ? GLX_PBUFFER_BIT : 0)
+ | (pAttrib[1] & EGL_PIXMAP_BIT ? GLX_PIXMAP_BIT : 0)
+ | (pAttrib[1] & EGL_WINDOW_BIT ? GLX_WINDOW_BIT : 0);
+ break;
+ case EGL_TRANSPARENT_TYPE:
+ aAttribList[cAttribs] = GLX_TRANSPARENT_TYPE;
+ aAttribList[cAttribs + 1] = pAttrib[1] == EGL_DONT_CARE ? GLX_DONT_CARE
+ : pAttrib[1] == EGL_NONE ? GLX_NONE
+ : pAttrib[1] == EGL_TRANSPARENT_RGB ? GLX_TRANSPARENT_RGB
+ : GL_FALSE;
+ break;
+ default:
+ return setEGLError(EGL_BAD_ATTRIBUTE);
+ }
+ cAttribs += 2;
+ }
+ }
+ if (cConfigCaveat != GLX_DONT_CARE || cConformant != GLX_DONT_CARE)
+ {
+ aAttribList[cAttribs] = GLX_CONFIG_CAVEAT;
+ aAttribList[cAttribs + 1] = cConformant == GL_FALSE ? GLX_NON_CONFORMANT_CONFIG
+ : cConfigCaveat == EGL_SLOW_CONFIG ? GLX_SLOW_CONFIG
+ : GLX_NONE;
+ cAttribs += 2;
+ }
+ aAttribList[cAttribs] = GLX_RENDER_TYPE;
+ aAttribList[cAttribs + 1] = GLX_RGBA_BIT;
+ cAttribs += 2;
+ if (paAttribs != NULL)
+ {
+ aAttribList[cAttribs] = None;
+ EGL_ASSERT(cAttribs < RT_ELEMENTS(aAttribList));
+ if (!(cRenderableType & EGL_OPENGL_BIT))
+ return setEGLError(EGL_BAD_ACCESS);
+ }
+ paFBConfigs = glXChooseFBConfig(pDisplay, DefaultScreen(pDisplay), paAttribs != NULL ? aAttribList : NULL, &caFBConfigs);
+ if (paFBConfigs == NULL)
+ return setEGLError(EGL_BAD_ACCESS);
+ *pcConfigs = caFBConfigs;
+ for (i = 0; (GLint)i < caConfigs && (GLint)i < caFBConfigs; ++i)
+ paConfigs[i] = (EGLConfig)paFBConfigs[i];
+ XFree(paFBConfigs);
+ return clearEGLError();
+}
+
+DECLEXPORT(EGLBoolean) eglGetConfigAttrib (EGLDisplay hDisplay, EGLConfig cConfig, EGLint cAttribute, EGLint *pValue)
+{
+ Display *pDisplay = (Display *)hDisplay;
+ int cGLXAttribute = convertEGLAttribToGLX(cAttribute);
+ int cValue;
+
+ if (!VALID_PTR(hDisplay))
+ return setEGLError(EGL_NOT_INITIALIZED);
+ if (!VALID_PTR(pValue))
+ return setEGLError(EGL_BAD_PARAMETER);
+ if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, GLX_FBCONFIG_ID, &cValue))
+ return setEGLError(EGL_BAD_CONFIG);
+ if (cGLXAttribute != None)
+ {
+ if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, cGLXAttribute, &cValue))
+ return setEGLError(EGL_BAD_ACCESS);
+ *pValue = cValue;
+ return clearEGLError();
+ }
+ switch (cAttribute)
+ {
+ case EGL_ALPHA_MASK_SIZE:
+ *pValue = 0;
+ return clearEGLError();
+ case EGL_LUMINANCE_SIZE:
+ if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, GLX_X_VISUAL_TYPE, &cValue))
+ return setEGLError(EGL_BAD_ACCESS);
+ if (cValue == GLX_STATIC_GRAY || cValue == GLX_GRAY_SCALE)
+ {
+ if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, GLX_RED_SIZE, &cValue))
+ return setEGLError(EGL_BAD_ACCESS);
+ *pValue = cValue;
+ }
+ else
+ *pValue = 0;
+ return clearEGLError();
+ case EGL_COLOR_BUFFER_TYPE:
+ if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, GLX_X_VISUAL_TYPE, &cValue))
+ return setEGLError(EGL_BAD_ACCESS);
+ if (cValue == GLX_STATIC_GRAY || cValue == GLX_GRAY_SCALE)
+ *pValue = EGL_LUMINANCE_BUFFER;
+ else
+ *pValue = EGL_RGB_BUFFER;
+ return clearEGLError();
+ case EGL_CONFIG_CAVEAT:
+ if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, GLX_CONFIG_CAVEAT, &cValue))
+ return setEGLError(EGL_BAD_ACCESS);
+ *pValue = cValue == GLX_NONE ? EGL_NONE : cValue == GLX_SLOW_CONFIG ? EGL_SLOW_CONFIG : GLX_NON_CONFORMANT_CONFIG;
+ return clearEGLError();
+ case EGL_CONFORMANT:
+ if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, GLX_CONFIG_CAVEAT, &cValue))
+ return setEGLError(EGL_BAD_ACCESS);
+ *pValue = cValue == GLX_NON_CONFORMANT_CONFIG ? 0 : EGL_OPENGL_BIT;
+ return clearEGLError();
+ case EGL_MATCH_NATIVE_PIXMAP:
+ case EGL_MIN_SWAP_INTERVAL:
+ case EGL_MAX_SWAP_INTERVAL:
+ return setEGLError(EGL_BAD_ACCESS);
+ case EGL_NATIVE_VISUAL_TYPE:
+ if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, GLX_X_VISUAL_TYPE, &cValue))
+ return setEGLError(EGL_BAD_ACCESS);
+ *pValue = cValue == GLX_STATIC_GRAY ? StaticGray
+ : cValue == GLX_STATIC_COLOR ? StaticColor
+ : cValue == GLX_TRUE_COLOR ? TrueColor
+ : cValue == GLX_GRAY_SCALE ? GrayScale
+ : cValue == GLX_PSEUDO_COLOR ? PseudoColor
+ : cValue == GLX_DIRECT_COLOR ? DirectColor
+ : -1;
+ return clearEGLError();
+ case EGL_RENDERABLE_TYPE:
+ *pValue = EGL_OPENGL_BIT;
+ return clearEGLError();
+ case EGL_SURFACE_TYPE:
+ if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, GLX_DRAWABLE_TYPE, &cValue))
+ return setEGLError(EGL_BAD_ACCESS);
+ *pValue = (cValue & GLX_PBUFFER_BIT ? EGL_PBUFFER_BIT : 0)
+ | (cValue & GLX_PIXMAP_BIT ? EGL_PIXMAP_BIT : 0)
+ | (cValue & GLX_WINDOW_BIT ? EGL_WINDOW_BIT : 0);
+ return clearEGLError();
+ case EGL_TRANSPARENT_TYPE:
+ if (glXGetFBConfigAttrib(pDisplay, (GLXFBConfig)cConfig, GLX_TRANSPARENT_TYPE, &cValue))
+ return setEGLError(EGL_BAD_ACCESS);
+ *pValue = cValue == GLX_NONE ? EGL_NONE
+ : cValue == GLX_TRANSPARENT_RGB ? EGL_TRANSPARENT_RGB
+ : EGL_FALSE;
+ return *pValue != EGL_FALSE ? clearEGLError() : setEGLError(EGL_BAD_ACCESS);
+ default:
+ return setEGLError(EGL_BAD_ATTRIBUTE);
+ }
+ return clearEGLError();
+}
+
+DECLEXPORT(EGLSurface) eglCreateWindowSurface(EGLDisplay hDisplay, EGLConfig config, EGLNativeWindowType hWindow,
+ const EGLint *paAttributes)
+{
+ Display *pDisplay = (Display *)hDisplay;
+ GLXWindow hGLXWindow;
+
+ if (!VALID_PTR(hDisplay))
+ {
+ setEGLError(EGL_NOT_INITIALIZED);
+ return EGL_NO_SURFACE;
+ }
+ if (paAttributes != NULL) /* Sanity test only. */
+ while (*paAttributes != EGL_NONE)
+ {
+ if (*paAttributes != EGL_RENDER_BUFFER)
+ {
+ setEGLError(EGL_BAD_MATCH);
+ return EGL_NO_SURFACE;
+ }
+ paAttributes += 2;
+ }
+ hGLXWindow = glXCreateWindow(pDisplay, (GLXFBConfig)config, (Window)hWindow, NULL);
+ if (hGLXWindow == None)
+ {
+ setEGLError(EGL_BAD_ALLOC);
+ return EGL_NO_SURFACE;
+ }
+ EGL_ASSERT(hGLXWindow < VBEGL_WINDOW_SURFACE); /* Greater than the maximum XID. */
+ clearEGLError();
+ return (EGLSurface)(hGLXWindow | VBEGL_WINDOW_SURFACE);
+}
+
+static void setAttribute(int *pcStoreIndex, int *pcCurIndex, int *paGLXAttributes, int cAttribute, int cValue)
+{
+ if (*pcStoreIndex < 0)
+ {
+ *pcStoreIndex = *pcCurIndex;
+ *pcCurIndex += 2;
+ paGLXAttributes[*pcStoreIndex] = cAttribute;
+ }
+ paGLXAttributes[*pcStoreIndex + 1] = cValue;
+}
+
+DECLEXPORT(EGLSurface) eglCreatePbufferSurface(EGLDisplay hDisplay, EGLConfig config, EGLint const *paAttributes)
+{
+ Display *pDisplay = (Display *)hDisplay;
+ enum { CPS_WIDTH = 0, CPS_HEIGHT, CPS_LARGEST, CPS_PRESERVED, CPS_TEX_FORMAT, CPS_TEX_TARGET, CPS_MIPMAP_TEX, CPS_END };
+ int acIndices[CPS_END];
+ int aAttributes[CPS_END * 2];
+ int cIndex = 0;
+ unsigned i;
+ GLXPbuffer hPbuffer;
+
+ if (!VALID_PTR(hDisplay))
+ {
+ setEGLError(EGL_NOT_INITIALIZED);
+ return EGL_NO_SURFACE;
+ }
+ for (i = 0; i < RT_ELEMENTS(acIndices); ++i)
+ acIndices[i] = -1;
+ if (paAttributes != NULL)
+ while (*paAttributes != EGL_NONE)
+ {
+ switch (*paAttributes)
+ {
+ case EGL_WIDTH:
+ setAttribute(&acIndices[CPS_WIDTH], &cIndex, aAttributes, GLX_PBUFFER_WIDTH, paAttributes[1]);
+ break;
+ case EGL_HEIGHT:
+ setAttribute(&acIndices[CPS_HEIGHT], &cIndex, aAttributes, GLX_LARGEST_PBUFFER, paAttributes[1]);
+ break;
+ case EGL_LARGEST_PBUFFER:
+ setAttribute(&acIndices[CPS_LARGEST], &cIndex, aAttributes, GLX_PBUFFER_HEIGHT, paAttributes[1]);
+ break;
+ case EGL_BUFFER_PRESERVED:
+ setAttribute(&acIndices[CPS_PRESERVED], &cIndex, aAttributes, GLX_PRESERVED_CONTENTS, paAttributes[1]);
+ break;
+ case EGL_TEXTURE_FORMAT:
+ setAttribute(&acIndices[CPS_TEX_FORMAT], &cIndex, aAttributes, GLX_TEXTURE_FORMAT_EXT, paAttributes[1]);
+ break;
+ case EGL_TEXTURE_TARGET:
+ setAttribute(&acIndices[CPS_TEX_TARGET], &cIndex, aAttributes, GLX_TEXTURE_TARGET_EXT, paAttributes[1]);
+ break;
+ case EGL_MIPMAP_TEXTURE:
+ setAttribute(&acIndices[CPS_MIPMAP_TEX], &cIndex, aAttributes, GLX_MIPMAP_TEXTURE_EXT, paAttributes[1]);
+ break;
+ case EGL_VG_ALPHA_FORMAT:
+ case EGL_VG_COLORSPACE:
+ {
+ setEGLError(EGL_BAD_MATCH);
+ return EGL_NO_SURFACE;
+ }
+ }
+ paAttributes += 2;
+ }
+ EGL_ASSERT((unsigned)cIndex < RT_ELEMENTS(aAttributes) - 1U);
+ aAttributes[cIndex + 1] = None;
+ hPbuffer = glXCreatePbuffer(pDisplay, (GLXFBConfig)config, aAttributes);
+ if (hPbuffer == None)
+ {
+ setEGLError(EGL_BAD_ALLOC);
+ return EGL_NO_SURFACE;
+ }
+ EGL_ASSERT(hPbuffer < VBEGL_WINDOW_SURFACE); /* Greater than the maximum XID. */
+ clearEGLError();
+ return (EGLSurface)(hPbuffer | VBEGL_PBUFFER_SURFACE);
+}
+
+DECLEXPORT(EGLSurface) eglCreatePixmapSurface(EGLDisplay hDisplay, EGLConfig config, EGLNativePixmapType hPixmap,
+ const EGLint *paAttributes)
+{
+ Display *pDisplay = (Display *)hDisplay;
+ GLXPixmap hGLXPixmap;
+
+ if (!VALID_PTR(hDisplay))
+ {
+ setEGLError(EGL_NOT_INITIALIZED);
+ return EGL_NO_SURFACE;
+ }
+ if (paAttributes != NULL) /* Sanity test only. */
+ if (*paAttributes != EGL_NONE)
+ {
+ if (*paAttributes == EGL_VG_COLORSPACE || *paAttributes == EGL_VG_ALPHA_FORMAT)
+ {
+ setEGLError(EGL_BAD_MATCH);
+ return EGL_NO_SURFACE;
+ }
+ else
+ {
+ setEGLError(EGL_BAD_ATTRIBUTE);
+ return EGL_NO_SURFACE;
+ }
+ }
+ hGLXPixmap = glXCreatePixmap(pDisplay, (GLXFBConfig)config, (Pixmap)hPixmap, NULL);
+ if (hGLXPixmap == None)
+ {
+ setEGLError(EGL_BAD_MATCH);
+ return EGL_NO_SURFACE;
+ }
+ EGL_ASSERT(hGLXPixmap < VBEGL_WINDOW_SURFACE); /* Greater than the maximum XID. */
+ clearEGLError();
+ return (EGLSurface)(hGLXPixmap | VBEGL_PIXMAP_SURFACE);
+}
+
+DECLEXPORT(EGLBoolean) eglDestroySurface(EGLDisplay hDisplay, EGLSurface hSurface)
+{
+ Display *pDisplay = (Display *)hDisplay;
+
+ if (!VALID_PTR(hDisplay))
+ return setEGLError(EGL_NOT_INITIALIZED);
+ switch ((GLXDrawable)hSurface & VBEGL_ANY_SURFACE)
+ {
+ case VBEGL_WINDOW_SURFACE:
+ glXDestroyWindow(pDisplay, (GLXWindow)hSurface & ~VBEGL_WINDOW_SURFACE);
+ return clearEGLError();
+ case VBEGL_PBUFFER_SURFACE:
+ glXDestroyPbuffer(pDisplay, (GLXPbuffer)hSurface & ~VBEGL_PBUFFER_SURFACE);
+ return clearEGLError();
+ case VBEGL_PIXMAP_SURFACE:
+ glXDestroyPixmap(pDisplay, (GLXPixmap)hSurface & ~VBEGL_PIXMAP_SURFACE);
+ return clearEGLError();
+ default:
+ return setEGLError(EGL_BAD_SURFACE);
+ }
+}
+
+DECLEXPORT(EGLBoolean) eglSurfaceAttrib(EGLDisplay hDisplay, EGLSurface hSurface, EGLint cAttribute, EGLint cValue)
+{
+ NOREF(hDisplay);
+ NOREF(hSurface);
+ NOREF(cValue);
+ switch (cAttribute)
+ {
+ case EGL_MIPMAP_LEVEL:
+ case EGL_MULTISAMPLE_RESOLVE:
+ case EGL_SWAP_BEHAVIOR:
+ return setEGLError(EGL_BAD_MATCH);
+ default:
+ return setEGLError(EGL_BAD_ATTRIBUTE);
+ }
+}
+
+DECLEXPORT(EGLBoolean) eglQuerySurface(EGLDisplay hDisplay, EGLSurface hSurface, EGLint cAttribute, EGLint *cValue)
+{
+ NOREF(hDisplay);
+ NOREF(hSurface);
+ NOREF(cAttribute);
+ NOREF(cValue);
+ return setEGLError(EGL_BAD_MATCH);
+}
+
+DECLEXPORT(EGLBoolean) eglBindTexImage(EGLDisplay hDisplay, EGLSurface hSurface, EGLint cBuffer)
+{
+ NOREF(hDisplay);
+ NOREF(hSurface);
+ NOREF(cBuffer);
+ return setEGLError(EGL_BAD_MATCH);
+}
+
+DECLEXPORT(EGLBoolean) eglReleaseTexImage(EGLDisplay hDisplay, EGLSurface hSurface, EGLint cBuffer)
+{
+ NOREF(hDisplay);
+ NOREF(hSurface);
+ NOREF(cBuffer);
+ return setEGLError(EGL_BAD_MATCH);
+}
+
+DECLEXPORT(EGLBoolean) eglBindAPI(EGLenum enmApi)
+{
+ return enmApi == EGL_OPENGL_API ? clearEGLError() : setEGLError(EGL_BAD_PARAMETER);
+}
+
+DECLEXPORT(EGLenum) eglQueryAPI(void)
+{
+ return EGL_OPENGL_API;
+}
+
+DECLEXPORT(EGLContext) eglCreateContext(EGLDisplay hDisplay, EGLConfig hConfig, EGLContext hSharedContext,
+ const EGLint *paAttribs)
+{
+ Display *pDisplay = (Display *)hDisplay;
+ GLXContext hNewContext;
+
+ if (!VALID_PTR(hDisplay))
+ {
+ setEGLError(EGL_NOT_INITIALIZED);
+ return EGL_NO_CONTEXT;
+ }
+ if (paAttribs != NULL && *paAttribs != EGL_NONE)
+ {
+ setEGLError(EGL_BAD_ATTRIBUTE);
+ return EGL_NO_CONTEXT;
+ }
+ hNewContext = glXCreateNewContext(pDisplay, (GLXFBConfig)hConfig, GLX_RGBA_TYPE, (GLXContext)hSharedContext, true);
+ if (hNewContext)
+ {
+ clearEGLError();
+ return (EGLContext)hNewContext;
+ }
+ setEGLError(EGL_BAD_MATCH);
+ return EGL_NO_CONTEXT;
+}
+
+DECLEXPORT(EGLBoolean) eglDestroyContext(EGLDisplay hDisplay, EGLContext hContext)
+{
+ Display *pDisplay = (Display *)hDisplay;
+
+ if (!VALID_PTR(hDisplay))
+ return setEGLError(EGL_NOT_INITIALIZED);
+ glXDestroyContext(pDisplay, (GLXContext) hContext);
+ return clearEGLError();
+}
+
+DECLEXPORT(EGLBoolean) eglMakeCurrent(EGLDisplay hDisplay, EGLSurface hDraw, EGLSurface hRead, EGLContext hContext)
+{
+ Display *pDisplay = (Display *)hDisplay;
+ GLXDrawable hGLXDraw = hDraw == EGL_NO_SURFACE ? None : (GLXDrawable)hDraw & ~VBEGL_ANY_SURFACE;
+ GLXDrawable hGLXRead = hRead == EGL_NO_SURFACE ? None : (GLXDrawable)hRead & ~VBEGL_ANY_SURFACE;
+ GLXContext hGLXContext = hContext == EGL_NO_CONTEXT ? None : (GLXContext)hContext;
+ struct VBEGLTLS *pTls = getTls();
+
+ if (!VALID_PTR(hDisplay) || !VALID_PTR(pTls))
+ return setEGLError(EGL_NOT_INITIALIZED);
+ if (glXMakeContextCurrent(pDisplay, hGLXDraw, hGLXRead, hGLXContext))
+ {
+ pTls->hCurrent = hContext;
+ pTls->hCurrentDraw = hDraw;
+ pTls->hCurrentRead = hRead;
+ return clearEGLError();
+ }
+ else
+ return setEGLError(EGL_BAD_MATCH);
+}
+
+DECLEXPORT(EGLContext) eglGetCurrentContext(void)
+{
+ struct VBEGLTLS *pTls = getTls();
+
+ if (!VALID_PTR(pTls))
+ return EGL_NO_CONTEXT;
+ clearEGLError();
+ return pTls->hCurrent;
+}
+
+DECLEXPORT(EGLSurface) eglGetCurrentSurface(EGLint cOp)
+{
+ struct VBEGLTLS *pTls = getTls();
+
+ if (!VALID_PTR(pTls))
+ return EGL_NO_SURFACE;
+ clearEGLError();
+ switch (cOp)
+ {
+ case EGL_DRAW:
+ return pTls->hCurrentDraw;
+ case EGL_READ:
+ return pTls->hCurrentRead;
+ default:
+ setEGLError(EGL_BAD_PARAMETER);
+ return EGL_NO_SURFACE;
+ }
+}
+
+DECLEXPORT(EGLDisplay) eglGetCurrentDisplay(void)
+{
+ struct VBEGLTLS *pTls;
+
+ pTls = getTls();
+ if (!VALID_PTR(pTls))
+ return EGL_NO_DISPLAY;
+ clearEGLError();
+ return pTls->hCurrentDisplay;
+}
+
+DECLEXPORT(EGLBoolean) eglQueryContext(EGLDisplay hDisplay, EGLContext hContext, EGLint cAttribute, EGLint *pcValue)
+{
+ Display *pDisplay = (Display *)hDisplay;
+
+ if (!VALID_PTR(hDisplay))
+ return setEGLError(EGL_NOT_INITIALIZED);
+ if (!VALID_PTR(pcValue))
+ return setEGLError(EGL_BAD_PARAMETER);
+ switch (cAttribute)
+ {
+ case EGL_CONFIG_ID:
+ {
+ int cValue = 0;
+
+ if (glXQueryContext(pDisplay, (GLXContext)hContext, GLX_FBCONFIG_ID, &cValue) == Success)
+ {
+ *pcValue = cValue;
+ return clearEGLError();
+ }
+ return setEGLError(EGL_BAD_MATCH);
+ }
+ case EGL_CONTEXT_CLIENT_TYPE:
+ *pcValue = EGL_OPENGL_API;
+ return clearEGLError();
+ case EGL_CONTEXT_CLIENT_VERSION:
+ *pcValue = 0;
+ return clearEGLError();
+ case EGL_RENDER_BUFFER:
+ *pcValue = EGL_BACK_BUFFER;
+ return clearEGLError();
+ default:
+ return setEGLError(EGL_BAD_ATTRIBUTE);
+ }
+}
+
+DECLEXPORT(EGLBoolean) eglWaitClient(void)
+{
+ glXWaitGL();
+ return clearEGLError();
+}
+
+DECLEXPORT(EGLBoolean) eglWaitGL(void)
+{
+ return setEGLError(EGL_BAD_PARAMETER); /* OpenGL ES only. */
+}
+
+DECLEXPORT(EGLBoolean) eglWaitNative(EGLint cEngine)
+{
+ if (cEngine != EGL_CORE_NATIVE_ENGINE)
+ return setEGLError(EGL_BAD_PARAMETER);
+ glXWaitX();
+ return clearEGLError();
+}
+
+DECLEXPORT(EGLBoolean) eglSwapBuffers(EGLDisplay hDisplay, EGLSurface hSurface)
+{
+ Display *pDisplay = (Display *)hDisplay;
+
+ if (!VALID_PTR(hDisplay))
+ return setEGLError(EGL_NOT_INITIALIZED);
+ glXSwapBuffers(pDisplay, (GLXDrawable)hSurface & ~VBEGL_ANY_SURFACE);
+ return clearEGLError();
+}
+
+/** @todo Work out how this fits over what Chromium has to offer. */
+DECLEXPORT(EGLBoolean) eglCopyBuffers(EGLDisplay hDisplay, EGLSurface hSurface, EGLNativePixmapType hPixmap)
+{
+ Display *pDisplay = (Display *)hDisplay;
+
+ if (!VALID_PTR(pDisplay))
+ return setEGLError(EGL_NOT_INITIALIZED);
+
+ NOREF(hSurface);
+ NOREF(hPixmap);
+ return setEGLError(EGL_BAD_MATCH);
+}
+
+DECLEXPORT(EGLBoolean) eglSwapInterval (EGLDisplay dpy, EGLint interval)
+{
+ NOREF(dpy);
+ NOREF(interval);
+ return EGL_TRUE;
+}
+
+typedef void (*VBEGLFuncPtr)(void);
+DECLEXPORT(VBEGLFuncPtr)eglGetProcAddress(const char *pszName)
+{
+ clearEGLError();
+ return glXGetProcAddress((const GLubyte *)pszName);
+}
+
+DECLEXPORT(EGLBoolean) eglReleaseThread()
+{
+ struct VBEGLTLS *pTls = getTls();
+
+ if (!(pTls))
+ return EGL_TRUE;
+ free(pTls);
+ /* Can this fail with ENOMEM? */
+ pthread_setspecific(g_tls, NULL);
+ return EGL_TRUE;
+}
diff --git a/src/VBox/Additions/common/crOpenGL/entrypoints.py b/src/VBox/Additions/common/crOpenGL/entrypoints.py
new file mode 100755
index 00000000..bdd93e75
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/entrypoints.py
@@ -0,0 +1,180 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+
+"""
+This module generates C entrypoints for all the OpenGL functions
+and the special Chromium meta/glue functions.
+"""
+
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+
+def GenerateEntrypoints(hacks = []):
+ """Emit code for all the OpenGL/Chromium entrypoints.
+ hacks is an optional list of functions which are special cased.
+ """
+
+ apiutil.CopyrightC()
+
+ print('#define GL_GLEXT_PROTOTYPES')
+ print('#include <stdio.h>')
+ print('#include <stdlib.h>')
+ print('#include <GL/gl.h>')
+ print('#include "chromium.h"')
+ print('#include "stub.h"')
+ print('#include "dri_glx.h"')
+ print('')
+ print('#ifdef __GNUC__')
+ print('# if (__GNUC__ << 16) + __GNUC_MINOR__ >= 0x40002')
+ print('# pragma GCC diagnostic ignored "-Wunused-parameter"')
+ print('# endif')
+ print('#endif')
+
+
+ # Get sorted list of dispatched functions.
+ # The order is very important - it must match cr_opcodes.h
+ # and spu_dispatch_table.h
+ keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+ for index in range(len(keys)):
+ func_name = keys[index]
+ if apiutil.Category(func_name) == "Chromium":
+ # this function is defined in stub.c
+ continue
+
+ return_type = apiutil.ReturnType(func_name)
+ params = apiutil.Parameters(func_name)
+
+ if func_name in hacks:
+ print("/* hacked entrypoint: %s */" % func_name)
+ if func_name == "TexImage3D":
+ # Pretty common: internalformat is GLenum, not GLint
+ print("void glTexImage3D( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels )")
+ print("{")
+ print("\tglim.TexImage3D( target, level, (GLint) internalformat, width, height, depth, border, format, type, pixels );")
+ print("}")
+ elif func_name == "TexImage2D":
+ # Pretty common: internalformat is GLenum, not GLint
+ print("void glTexImage2D( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels )")
+ print("{")
+ print("\tglim.TexImage2D( target, level, (GLint) internalformat, width, height, border, format, type, pixels );")
+ print("}")
+ elif func_name == "TexImage1D":
+ # Pretty common: internalformat is GLenum, not GLint
+ print("void glTexImage1D( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels )")
+ print("{")
+ print("\tglim.TexImage1D( target, level, (GLint) internalformat, width, border, format, type, pixels );")
+ print("}")
+ elif func_name == "EdgeFlagPointer":
+ # second arg is GLboolean instead of GLvoid
+ print("void glEdgeFlagPointer( GLsizei stride, const GLboolean *pointer )")
+ print("{")
+ print("\tglim.EdgeFlagPointer( stride, pointer );")
+ print("}")
+ elif func_name == "ProgramParameters4fvNV":
+ print("void glProgramParameters4fvNV( GLenum target, GLuint index, GLuint num, const GLfloat *params )")
+ print("{")
+ print("\tglim.ProgramParameters4fvNV( target, index, num, params );")
+ print("}")
+ elif func_name == "MultiDrawElementsEXT":
+ print("void glMultiDrawElementsEXT(GLenum mode, GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount)")
+ print("{")
+ print("\tglim.MultiDrawElementsEXT(mode, count,type, indices, primcount);")
+ print("}")
+ elif func_name == "ProgramParameters4dvNV":
+ print("void glProgramParameters4dvNV( GLenum target, GLuint index, GLuint num, const GLdouble *params )")
+ print("{")
+ print("\tglim.ProgramParameters4dvNV( target, index, num, params );")
+ print("}")
+ else:
+ # the usual path
+ print("%s VBOXGLTAG(gl%s)(%s);" % (return_type, func_name, apiutil.MakeDeclarationString(params)))
+ print("")
+ print("%s VBOXGLTAG(gl%s)(%s)" % (return_type, func_name, apiutil.MakeDeclarationString(params)))
+ print("{")
+ print("\t", end="")
+ if return_type != "void":
+ print("return ", end=" ")
+ print("glim.%s(%s);" % (func_name, apiutil.MakeCallString(params)))
+ print("}")
+ print("")
+
+ print('/*')
+ print('* Aliases')
+ print('*/')
+
+ # Now loop over all the functions and take care of any aliases
+ allkeys = apiutil.GetAllFunctions(sys.argv[1]+"/APIspec.txt")
+ for func_name in allkeys:
+ if "omit" in apiutil.ChromiumProps(func_name):
+ continue
+
+ if func_name in keys:
+ # we already processed this function earlier
+ continue
+
+ # alias is the function we're aliasing
+ alias = apiutil.Alias(func_name)
+ if alias:
+ if func_name in hacks:
+ print("/* hacked entrypoint: %s */" % func_name)
+ if func_name == "MultiDrawArrays":
+ print("void glMultiDrawArrays( GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount )")
+ print("{")
+ print("\tglim.MultiDrawArraysEXT( mode, (GLint*)first, (GLsizei*)count, primcount );")
+ print("}")
+ elif func_name == "BufferData":
+ print("void glBufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage)")
+ print("{")
+ print("\tglim.BufferDataARB(target, size, data, usage);")
+ print("}")
+ elif func_name == "BufferSubData":
+ print("void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data)")
+ print("{")
+ print("\tglim.BufferSubDataARB(target, offset, size, data);")
+ print("}")
+ elif func_name == "GetBufferSubData":
+ print("void glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data)")
+ print("{")
+ print("\tglim.GetBufferSubDataARB(target, offset, size, data);")
+ print("}")
+ else:
+ return_type = apiutil.ReturnType(func_name)
+ params = apiutil.Parameters(func_name)
+ print("%s VBOXGLTAG(gl%s)(%s);" % (return_type, func_name, apiutil.MakeDeclarationString(params)))
+ print("")
+ print("%s VBOXGLTAG(gl%s)(%s)" % (return_type, func_name, apiutil.MakeDeclarationString(params)))
+ print("{")
+ print("\t", end="")
+ if return_type != "void":
+ print("return ", end=" ")
+ print("glim.%s(%s);" % (alias, apiutil.MakeCallString(params)))
+ print("}")
+ print("")
+
+ print('/*')
+ print('* No-op stubs')
+ print('*/')
+
+ # Now generate no-op stub functions
+ for func_name in allkeys:
+ if "stub" in apiutil.ChromiumProps(func_name):
+ return_type = apiutil.ReturnType(func_name)
+ params = apiutil.Parameters(func_name)
+
+ print("%s VBOXGLTAG(gl%s)(%s);" % (return_type, func_name, apiutil.MakeDeclarationString(params)))
+ print("")
+ print("%s VBOXGLTAG(gl%s)(%s)" % (return_type, func_name, apiutil.MakeDeclarationString(params)))
+ print("{")
+ if return_type != "void":
+ print("return (%s) 0" % return_type)
+ print("}")
+ print("")
+
diff --git a/src/VBox/Additions/common/crOpenGL/fakedri_drv.c b/src/VBox/Additions/common/crOpenGL/fakedri_drv.c
new file mode 100644
index 00000000..1fab45b0
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/fakedri_drv.c
@@ -0,0 +1,878 @@
+/* $Id: fakedri_drv.c $ */
+/** @file
+ * VBox OpenGL DRI driver functions
+ */
+
+/*
+ * Copyright (C) 2009-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#define _GNU_SOURCE 1
+
+#include "cr_error.h"
+#include "cr_gl.h"
+#include "cr_mem.h"
+#include "stub.h"
+#include "fakedri_drv.h"
+#include "dri_glx.h"
+#include "iprt/mem.h"
+#include <iprt/errcore.h>
+#include <dlfcn.h>
+#include <elf.h>
+#include <unistd.h>
+
+#if defined(RT_OS_FREEBSD)
+#include <sys/param.h>
+#include <fcntl.h>
+#include <gelf.h>
+#include <libelf.h>
+#include <string.h>
+#endif
+
+/** X server message type definitions. */
+typedef enum {
+ X_PROBED, /* Value was probed */
+ X_CONFIG, /* Value was given in the config file */
+ X_DEFAULT, /* Value is a default */
+ X_CMDLINE, /* Value was given on the command line */
+ X_NOTICE, /* Notice */
+ X_ERROR, /* Error message */
+ X_WARNING, /* Warning message */
+ X_INFO, /* Informational message */
+ X_NONE, /* No prefix */
+ X_NOT_IMPLEMENTED, /* Not implemented */
+ X_UNKNOWN = -1 /* unknown -- this must always be last */
+} MessageType;
+
+#define VBOX_NO_MESA_PATCH_REPORTS
+
+//#define DEBUG_DRI_CALLS
+
+/// @todo this could be different...
+#ifdef RT_ARCH_AMD64
+# ifdef RT_OS_FREEBSD
+# define DRI_DEFAULT_DRIVER_DIR "/usr/local/lib/dri"
+# define DRI_XORG_DRV_DIR "/usr/local/lib/xorg/modules/drivers/"
+# else
+# define DRI_DEFAULT_DRIVER_DIR "/usr/lib64/dri:/usr/lib/dri:/usr/lib/x86_64-linux-gnu/dri:/usr/lib/xorg/modules/dri"
+# define DRI_XORG_DRV_DIR "/usr/lib/xorg/modules/drivers/"
+# endif
+#else
+# ifdef RT_OS_FREEBSD
+# define DRI_DEFAULT_DRIVER_DIR "/usr/local/lib/dri"
+# define DRI_XORG_DRV_DIR "/usr/local/lib/xorg/modules/drivers/"
+# else
+# define DRI_DEFAULT_DRIVER_DIR "/usr/lib/dri:/usr/lib/i386-linux-gnu/dri:/usr/lib/xorg/modules/dri"
+# define DRI_XORG_DRV_DIR "/usr/lib/xorg/modules/drivers/"
+# endif
+#endif
+
+#ifdef DEBUG_DRI_CALLS
+ #define SWDRI_SHOWNAME(pext, func) \
+ crDebug("SWDRI: sc %s->%s", #pext, #func)
+#else
+ #define SWDRI_SHOWNAME(pext, func)
+#endif
+
+#define SWDRI_SAFECALL(pext, func, ...) \
+ SWDRI_SHOWNAME(pext, func); \
+ if (pext && pext->func){ \
+ (*pext->func)(__VA_ARGS__); \
+ } else { \
+ crDebug("swcore_call NULL for "#func); \
+ }
+
+#define SWDRI_SAFERET(pext, func, ...) \
+ SWDRI_SHOWNAME(pext, func); \
+ if (pext && pext->func){ \
+ return (*pext->func)(__VA_ARGS__); \
+ } else { \
+ crDebug("swcore_call NULL for "#func); \
+ return 0; \
+ }
+
+#define SWDRI_SAFERET_CORE(func, ...) SWDRI_SAFERET(gpSwDriCoreExternsion, func, __VA_ARGS__)
+#define SWDRI_SAFECALL_CORE(func, ...) SWDRI_SAFECALL(gpSwDriCoreExternsion, func, __VA_ARGS__)
+#define SWDRI_SAFERET_SWRAST(func, ...) SWDRI_SAFERET(gpSwDriSwrastExtension, func, __VA_ARGS__)
+#define SWDRI_SAFECALL_SWRAST(func, ...) SWDRI_SAFECALL(gpSwDriSwrastExtension, func, __VA_ARGS__)
+
+#ifndef PAGESIZE
+#define PAGESIZE 4096
+#endif
+
+#ifdef RT_ARCH_AMD64
+# define DRI_ELFSYM Elf64_Sym
+#else
+# define DRI_ELFSYM Elf32_Sym
+#endif
+
+#ifdef RT_ARCH_AMD64
+typedef struct _FAKEDRI_PatchNode
+{
+ const char* psFuncName;
+ void *pDstStart, *pDstEnd;
+ const void *pSrcStart, *pSrcEnd;
+
+ struct _FAKEDRI_PatchNode *pNext;
+} FAKEDRI_PatchNode;
+static FAKEDRI_PatchNode *g_pFreeList=NULL, *g_pRepatchList=NULL;
+#endif
+
+static struct _glapi_table* vbox_glapi_table = NULL;
+fakedri_glxapi_table glxim;
+
+static const __DRIextension **gppSwDriExternsion = NULL;
+static const __DRIcoreExtension *gpSwDriCoreExternsion = NULL;
+static const __DRIswrastExtension *gpSwDriSwrastExtension = NULL;
+
+extern const __DRIextension * __driDriverExtensions[];
+
+#define VBOX_SET_MESA_FUNC(table, name, func) \
+ if (_glapi_get_proc_offset(name)>=0) SET_by_offset(table, _glapi_get_proc_offset(name), func); \
+ else crWarning("%s not found in mesa table", name)
+
+#define GLAPI_ENTRY(Func) VBOX_SET_MESA_FUNC(vbox_glapi_table, "gl"#Func, cr_gl##Func);
+
+static void
+vboxPatchMesaExport(const char* psFuncName, const void *pStart, const void *pEnd);
+
+static void
+vboxPatchMesaGLAPITable()
+{
+ void *pGLTable;
+
+ pGLTable = (void *)_glapi_get_dispatch();
+ vbox_glapi_table = crAlloc(_glapi_get_dispatch_table_size() * sizeof (void *));
+ if (!vbox_glapi_table)
+ {
+ crError("Not enough memory to allocate dispatch table");
+ }
+ crMemcpy(vbox_glapi_table, pGLTable, _glapi_get_dispatch_table_size() * sizeof (void *));
+
+ #include "fakedri_glfuncsList.h"
+
+ VBOX_SET_MESA_FUNC(vbox_glapi_table, "glBlendEquationSeparateEXT", cr_glBlendEquationSeparate);
+ VBOX_SET_MESA_FUNC(vbox_glapi_table, "glSampleMaskSGIS", cr_glSampleMaskEXT);
+ VBOX_SET_MESA_FUNC(vbox_glapi_table, "glSamplePatternSGIS", cr_glSamplePatternEXT);
+ VBOX_SET_MESA_FUNC(vbox_glapi_table, "glWindowPos2dMESA", cr_glWindowPos2d);
+ VBOX_SET_MESA_FUNC(vbox_glapi_table, "glWindowPos2dvMESA", cr_glWindowPos2dv);
+ VBOX_SET_MESA_FUNC(vbox_glapi_table, "glWindowPos2fMESA", cr_glWindowPos2f);
+ VBOX_SET_MESA_FUNC(vbox_glapi_table, "glWindowPos2fvMESA", cr_glWindowPos2fv);
+ VBOX_SET_MESA_FUNC(vbox_glapi_table, "glWindowPos2iMESA", cr_glWindowPos2i);
+ VBOX_SET_MESA_FUNC(vbox_glapi_table, "glWindowPos2ivMESA", cr_glWindowPos2iv);
+ VBOX_SET_MESA_FUNC(vbox_glapi_table, "glWindowPos2sMESA", cr_glWindowPos2s);
+ VBOX_SET_MESA_FUNC(vbox_glapi_table, "glWindowPos2svMESA", cr_glWindowPos2sv);
+ VBOX_SET_MESA_FUNC(vbox_glapi_table, "glWindowPos3dMESA", cr_glWindowPos3d);
+ VBOX_SET_MESA_FUNC(vbox_glapi_table, "glWindowPos3dvMESA", cr_glWindowPos3dv);
+ VBOX_SET_MESA_FUNC(vbox_glapi_table, "glWindowPos3fMESA", cr_glWindowPos3f);
+ VBOX_SET_MESA_FUNC(vbox_glapi_table, "glWindowPos3fvMESA", cr_glWindowPos3fv);
+ VBOX_SET_MESA_FUNC(vbox_glapi_table, "glWindowPos3iMESA", cr_glWindowPos3i);
+ VBOX_SET_MESA_FUNC(vbox_glapi_table, "glWindowPos3ivMESA", cr_glWindowPos3iv);
+ VBOX_SET_MESA_FUNC(vbox_glapi_table, "glWindowPos3sMESA", cr_glWindowPos3s);
+ VBOX_SET_MESA_FUNC(vbox_glapi_table, "glWindowPos3svMESA", cr_glWindowPos3sv);
+
+ _glapi_set_dispatch(vbox_glapi_table);
+};
+#undef GLAPI_ENTRY
+
+#define GLXAPI_ENTRY(Func) pGLXTable->Func = VBOXGLXTAG(glX##Func);
+static void
+vboxFillGLXAPITable(fakedri_glxapi_table *pGLXTable)
+{
+ #include "fakedri_glxfuncsList.h"
+}
+#undef GLXAPI_ENTRY
+
+static void
+vboxApplyPatch(const char* psFuncName, void *pDst, const void *pSrc, unsigned long size)
+{
+ void *alPatch;
+ int rv;
+
+ /* Get aligned start address we're going to patch*/
+ alPatch = (void*) ((uintptr_t)pDst & ~(uintptr_t)(PAGESIZE-1));
+
+#ifndef VBOX_NO_MESA_PATCH_REPORTS
+ crDebug("MProtecting: %p, %li", alPatch, pDst-alPatch+size);
+#endif
+
+ /* Get write access to mesa functions */
+ rv = RTMemProtect(alPatch, pDst-alPatch+size, RTMEM_PROT_READ|RTMEM_PROT_WRITE|RTMEM_PROT_EXEC);
+ if (RT_FAILURE(rv))
+ {
+ crError("mprotect failed with %x (%s)", rv, psFuncName);
+ }
+
+#ifndef VBOX_NO_MESA_PATCH_REPORTS
+ crDebug("Writing %li bytes to %p from %p", size, pDst, pSrc);
+#endif
+
+ crMemcpy(pDst, pSrc, size);
+
+ /** @todo Restore the protection, probably have to check what was it before us...*/
+ rv = RTMemProtect(alPatch, pDst-alPatch+size, RTMEM_PROT_READ|RTMEM_PROT_EXEC);
+ if (RT_FAILURE(rv))
+ {
+ crError("mprotect2 failed with %x (%s)", rv, psFuncName);
+ }
+}
+
+#define FAKEDRI_JMP64_PATCH_SIZE 13
+
+#if defined(RT_OS_FREEBSD)
+/* Provide basic dladdr1 flags */
+enum {
+ RTLD_DL_SYMENT = 1
+};
+
+/* Provide a minimal local version of dladdr1 */
+static int
+dladdr1(const void *address, Dl_info *dlip, void **info, int flags)
+{
+ static DRI_ELFSYM desym;
+ GElf_Sym sym;
+ GElf_Shdr shdr;
+ Elf *elf;
+ Elf_Scn *scn;
+ Elf_Data *data;
+ int ret, fd, count, i;
+
+ /* Initialize variables */
+ fd = -1;
+ elf = NULL;
+
+ /* Call dladdr first */
+ ret = dladdr(address, dlip);
+ if (ret == 0) goto err_exit;
+
+ /* Check for supported flags */
+ if (flags != RTLD_DL_SYMENT) return 1;
+
+ /* Open shared library's ELF file */
+ if (elf_version(EV_CURRENT) == EV_NONE) goto err_exit;
+ fd = open(dlip->dli_fname, O_RDONLY);
+ if (fd < 0) goto err_exit;
+ elf = elf_begin(fd, ELF_C_READ, NULL);
+ if (elf == NULL) goto err_exit;
+
+ /* Find the '.dynsym' section */
+ scn = elf_nextscn(elf, NULL);
+ while (scn != NULL) {
+ if (gelf_getshdr(scn, &shdr) == NULL) goto err_exit;
+ if (shdr.sh_type == SHT_DYNSYM) break;
+ scn = elf_nextscn(elf, scn);
+ }
+ if (scn == NULL) goto err_exit;
+
+ /* Search for the requested symbol by name and offset */
+ data = elf_getdata(scn, NULL);
+ count = shdr.sh_size / shdr.sh_entsize;
+ for (i = 0; i < count; i++) {
+ gelf_getsym(data, i, &sym);
+ if ((strcmp(dlip->dli_sname,
+ elf_strptr(elf, shdr.sh_link, sym.st_name)) == 0) &&
+ (sym.st_value == (dlip->dli_saddr - dlip->dli_fbase))) {
+ break;
+ }
+ }
+
+ /* Close ELF file */
+ elf_end(elf);
+ close(fd);
+
+ /* Return symbol entry in native format */
+ desym.st_name = sym.st_name;
+ desym.st_info = sym.st_info;
+ desym.st_other = sym.st_other;
+ desym.st_shndx = sym.st_shndx;
+ desym.st_value = sym.st_value;
+ desym.st_size = sym.st_size;
+ *info = &desym;
+ return 1;
+
+ /* Error handler */
+err_exit:
+ if (elf != NULL) elf_end(elf);
+ if (fd >= 0) close(fd);
+ return 0;
+}
+#endif
+
+static void
+vboxPatchMesaExport(const char* psFuncName, const void *pStart, const void *pEnd)
+{
+ Dl_info dlip;
+ DRI_ELFSYM* sym=0;
+ int rv;
+ void *alPatch;
+ void *pMesaEntry;
+ char patch[FAKEDRI_JMP64_PATCH_SIZE];
+ void *shift;
+ int ignore_size=false;
+
+#ifndef VBOX_NO_MESA_PATCH_REPORTS
+ crDebug("\nvboxPatchMesaExport: %s", psFuncName);
+#endif
+
+ pMesaEntry = dlsym(RTLD_DEFAULT, psFuncName);
+
+ if (!pMesaEntry)
+ {
+ crDebug("%s not defined in current scope, are we being loaded by mesa's libGL.so?", psFuncName);
+ return;
+ }
+
+ rv = dladdr1(pMesaEntry, &dlip, (void**)&sym, RTLD_DL_SYMENT);
+ if (!rv || !sym)
+ {
+ crError("Failed to get size for %p(%s)", pMesaEntry, psFuncName);
+ return;
+ }
+
+#if VBOX_OGL_GLX_USE_CSTUBS
+ {
+ Dl_info dlip1;
+ DRI_ELFSYM* sym1=0;
+ int rv;
+
+ rv = dladdr1(pStart, &dlip1, (void**)&sym1, RTLD_DL_SYMENT);
+ if (!rv || !sym1)
+ {
+ crError("Failed to get size for vbox %p", pStart);
+ return;
+ }
+
+ pEnd = pStart + sym1->st_size;
+# ifndef VBOX_NO_MESA_PATCH_REPORTS
+ crDebug("VBox Entry: %p, start: %p(%s:%s), size: %li", pStart, dlip1.dli_saddr, dlip1.dli_fname, dlip1.dli_sname, sym1->st_size);
+# endif
+ }
+#endif
+
+#ifndef VBOX_NO_MESA_PATCH_REPORTS
+ crDebug("Mesa Entry: %p, start: %p(%s:%s), size: %li", pMesaEntry, dlip.dli_saddr, dlip.dli_fname, dlip.dli_sname, sym->st_size);
+ crDebug("VBox code: start: %p, end %p, size: %li", pStart, pEnd, pEnd-pStart);
+#endif
+
+#ifndef VBOX_OGL_GLX_USE_CSTUBS
+ if (sym->st_size<(pEnd-pStart))
+#endif
+ {
+#ifdef RT_ARCH_AMD64
+ int64_t offset;
+#endif
+ /* Try to insert 5 bytes jmp/jmpq to our stub code */
+
+ if (sym->st_size<5)
+ {
+ /** @todo we don't really know the size of targeted static function, but it's long enough in practice. We will also patch same place twice, but it's ok.*/
+ if (!crStrcmp(psFuncName, "glXDestroyContext") || !crStrcmp(psFuncName, "glXFreeContextEXT"))
+ {
+ if (((unsigned char*)dlip.dli_saddr)[0]==0xEB)
+ {
+ /*it's a rel8 jmp, so we're going to patch the place it targets instead of jmp itself*/
+ dlip.dli_saddr = (void*) ((intptr_t)dlip.dli_saddr + ((char*)dlip.dli_saddr)[1] + 2);
+ ignore_size = true;
+ }
+ else
+ {
+ crError("Can't patch size is too small.(%s)", psFuncName);
+ return;
+ }
+ }
+ else if (!crStrcmp(psFuncName, "glXCreateGLXPixmapMESA"))
+ {
+ /** @todo it's just a return 0, which we're fine with for now*/
+ return;
+ }
+ else
+ {
+ crError("Can't patch size is too small.(%s)", psFuncName);
+ return;
+ }
+ }
+
+ shift = (void*)((intptr_t)pStart-((intptr_t)dlip.dli_saddr+5));
+#ifdef RT_ARCH_AMD64
+ offset = (intptr_t)shift;
+ if (offset>INT32_MAX || offset<INT32_MIN)
+ {
+ /*try to insert 64bit abs jmp*/
+ if (sym->st_size>=FAKEDRI_JMP64_PATCH_SIZE || ignore_size)
+ {
+# ifndef VBOX_NO_MESA_PATCH_REPORTS
+ crDebug("Inserting movq/jmp instead");
+# endif
+ /*add 64bit abs jmp*/
+ patch[0] = 0x49; /*movq %r11,imm64*/
+ patch[1] = 0xBB;
+ crMemcpy(&patch[2], &pStart, 8);
+ patch[10] = 0x41; /*jmp *%r11*/
+ patch[11] = 0xFF;
+ patch[12] = 0xE3;
+ pStart = &patch[0];
+ pEnd = &patch[FAKEDRI_JMP64_PATCH_SIZE];
+ }
+ else
+ {
+ FAKEDRI_PatchNode *pNode;
+# ifndef VBOX_NO_MESA_PATCH_REPORTS
+ crDebug("Can't patch offset is too big. Pushing for 2nd pass(%s)", psFuncName);
+# endif
+ /*Add patch node to repatch with chain jmps in 2nd pass*/
+ pNode = (FAKEDRI_PatchNode *)crAlloc(sizeof(FAKEDRI_PatchNode));
+ if (!pNode)
+ {
+ crError("Not enough memory.");
+ return;
+ }
+ pNode->psFuncName = psFuncName;
+ pNode->pDstStart = dlip.dli_saddr;
+ pNode->pDstEnd = dlip.dli_saddr+sym->st_size;
+ pNode->pSrcStart = pStart;
+ pNode->pSrcEnd = pEnd;
+ pNode->pNext = g_pRepatchList;
+ g_pRepatchList = pNode;
+ return;
+ }
+ }
+ else
+#endif
+ {
+#ifndef VBOX_NO_MESA_PATCH_REPORTS
+ crDebug("Inserting jmp[q] with shift %p instead", shift);
+#endif
+ patch[0] = 0xE9;
+ crMemcpy(&patch[1], &shift, 4);
+ pStart = &patch[0];
+ pEnd = &patch[5];
+ }
+ }
+
+ vboxApplyPatch(psFuncName, dlip.dli_saddr, pStart, pEnd-pStart);
+
+#ifdef RT_ARCH_AMD64
+ /*Add rest of mesa function body to free list*/
+ if (sym->st_size-(pEnd-pStart)>=FAKEDRI_JMP64_PATCH_SIZE)
+ {
+ FAKEDRI_PatchNode *pNode = (FAKEDRI_PatchNode *)crAlloc(sizeof(FAKEDRI_PatchNode));
+ if (pNode)
+ {
+ pNode->psFuncName = psFuncName;
+ pNode->pDstStart = dlip.dli_saddr+(pEnd-pStart);
+ pNode->pDstEnd = dlip.dli_saddr+sym->st_size;
+ pNode->pSrcStart = dlip.dli_saddr;
+ pNode->pSrcEnd = NULL;
+ pNode->pNext = g_pFreeList;
+ g_pFreeList = pNode;
+# ifndef VBOX_NO_MESA_PATCH_REPORTS
+ crDebug("Added free node %s, func start=%p, free start=%p, size=%#lx",
+ psFuncName, pNode->pSrcStart, pNode->pDstStart, pNode->pDstEnd-pNode->pDstStart);
+# endif
+ }
+ }
+#endif
+}
+
+#ifdef RT_ARCH_AMD64
+static void
+vboxRepatchMesaExports(void)
+{
+ FAKEDRI_PatchNode *pFreeNode, *pPatchNode;
+ int64_t offset;
+ char patch[FAKEDRI_JMP64_PATCH_SIZE];
+
+ pPatchNode = g_pRepatchList;
+ while (pPatchNode)
+ {
+# ifndef VBOX_NO_MESA_PATCH_REPORTS
+ crDebug("\nvboxRepatchMesaExports %s", pPatchNode->psFuncName);
+# endif
+ /*find free place in mesa functions, to place 64bit jump to our stub code*/
+ pFreeNode = g_pFreeList;
+ while (pFreeNode)
+ {
+ if (pFreeNode->pDstEnd-pFreeNode->pDstStart>=FAKEDRI_JMP64_PATCH_SIZE)
+ {
+ offset = ((intptr_t)pFreeNode->pDstStart-((intptr_t)pPatchNode->pDstStart+5));
+ if (offset<=INT32_MAX && offset>=INT32_MIN)
+ {
+ break;
+ }
+ }
+ pFreeNode=pFreeNode->pNext;
+ }
+
+ if (!pFreeNode)
+ {
+ crError("Failed to find free space, to place repatch for %s.", pPatchNode->psFuncName);
+ return;
+ }
+
+ /*add 32bit rel jmp, from mesa orginal function to free space in other mesa function*/
+ patch[0] = 0xE9;
+ crMemcpy(&patch[1], &offset, 4);
+# ifndef VBOX_NO_MESA_PATCH_REPORTS
+ crDebug("Adding jmp from mesa %s to mesa %s+%#lx", pPatchNode->psFuncName, pFreeNode->psFuncName,
+ pFreeNode->pDstStart-pFreeNode->pSrcStart);
+# endif
+ vboxApplyPatch(pPatchNode->psFuncName, pPatchNode->pDstStart, &patch[0], 5);
+
+ /*add 64bit abs jmp, from free space to our stub code*/
+ patch[0] = 0x49; /*movq %r11,imm64*/
+ patch[1] = 0xBB;
+ crMemcpy(&patch[2], &pPatchNode->pSrcStart, 8);
+ patch[10] = 0x41; /*jmp *%r11*/
+ patch[11] = 0xFF;
+ patch[12] = 0xE3;
+# ifndef VBOX_NO_MESA_PATCH_REPORTS
+ crDebug("Adding jmp from mesa %s+%#lx to vbox %s", pFreeNode->psFuncName, pFreeNode->pDstStart-pFreeNode->pSrcStart,
+ pPatchNode->psFuncName);
+# endif
+ vboxApplyPatch(pFreeNode->psFuncName, pFreeNode->pDstStart, &patch[0], FAKEDRI_JMP64_PATCH_SIZE);
+ /*mark this space as used*/
+ pFreeNode->pDstStart = pFreeNode->pDstStart+FAKEDRI_JMP64_PATCH_SIZE;
+
+ pPatchNode = pPatchNode->pNext;
+ }
+}
+
+static void
+vboxFakeDriFreeList(FAKEDRI_PatchNode *pList)
+{
+ FAKEDRI_PatchNode *pNode;
+
+ while (pList)
+ {
+ pNode=pList;
+ pList=pNode->pNext;
+ crFree(pNode);
+ }
+}
+#endif
+
+#ifdef VBOX_OGL_GLX_USE_CSTUBS
+static void
+# define GLXAPI_ENTRY(Func) vboxPatchMesaExport("glX"#Func, &vbox_glX##Func, NULL);
+vboxPatchMesaExports()
+#else
+static void
+# define GLXAPI_ENTRY(Func) vboxPatchMesaExport("glX"#Func, &vbox_glX##Func, &vbox_glX##Func##_EndProc);
+vboxPatchMesaExports()
+#endif
+{
+ crDebug("Patching mesa glx entries");
+ #include "fakedri_glxfuncsList.h"
+
+#ifdef RT_ARCH_AMD64
+ vboxRepatchMesaExports();
+ vboxFakeDriFreeList(g_pRepatchList);
+ g_pRepatchList = NULL;
+ vboxFakeDriFreeList(g_pFreeList);
+ g_pFreeList = NULL;
+#endif
+}
+#undef GLXAPI_ENTRY
+
+bool vbox_load_sw_dri()
+{
+ const char *libPaths, *p, *next;;
+ char realDriverName[200];
+ void *handle;
+ int len, i;
+
+ /*code from Mesa-7.2/src/glx/x11/dri_common.c:driOpenDriver*/
+
+ libPaths = NULL;
+ if (geteuid() == getuid()) {
+ /* don't allow setuid apps to use LIBGL_DRIVERS_PATH */
+ libPaths = getenv("LIBGL_DRIVERS_PATH");
+ if (!libPaths)
+ libPaths = getenv("LIBGL_DRIVERS_DIR"); /* deprecated */
+ }
+ if (libPaths == NULL)
+ libPaths = DRI_DEFAULT_DRIVER_DIR;
+
+ handle = NULL;
+ for (p = libPaths; *p; p = next)
+ {
+ next = strchr(p, ':');
+ if (next == NULL)
+ {
+ len = strlen(p);
+ next = p + len;
+ }
+ else
+ {
+ len = next - p;
+ next++;
+ }
+
+ snprintf(realDriverName, sizeof realDriverName, "%.*s/%s_dri.so", len, p, "swrast");
+ crDebug("trying %s", realDriverName);
+ handle = dlopen(realDriverName, RTLD_NOW | RTLD_LOCAL);
+ if (handle) break;
+ }
+
+ /*end code*/
+
+ if (handle) gppSwDriExternsion = dlsym(handle, "__driDriverExtensions");
+
+ if (!gppSwDriExternsion)
+ {
+ crDebug("%s doesn't export __driDriverExtensions", realDriverName);
+ return false;
+ }
+ crDebug("loaded %s", realDriverName);
+
+ for (i = 0; gppSwDriExternsion[i]; i++)
+ {
+ if (strcmp(gppSwDriExternsion[i]->name, __DRI_CORE) == 0)
+ gpSwDriCoreExternsion = (__DRIcoreExtension *) gppSwDriExternsion[i];
+ if (strcmp(gppSwDriExternsion[i]->name, __DRI_SWRAST) == 0)
+ gpSwDriSwrastExtension = (__DRIswrastExtension *) gppSwDriExternsion[i];
+ }
+
+ return gpSwDriCoreExternsion && gpSwDriSwrastExtension;
+}
+
+void __attribute__ ((constructor)) vbox_install_into_mesa(void)
+{
+ {
+#ifdef _X_ATTRIBUTE_PRINTF
+ void (*pxf86Msg)(MessageType type, const char *format, ...) _X_ATTRIBUTE_PRINTF(2,3);
+#else
+ void (*pxf86Msg)(MessageType type, const char *format, ...) _printf_attribute(2,3);
+#endif
+
+ pxf86Msg = dlsym(RTLD_DEFAULT, "xf86Msg");
+ if (pxf86Msg)
+ {
+ pxf86Msg(X_INFO, "Next line is added to allow vboxvideo_drv.so to appear as whitelisted driver\n");
+ pxf86Msg(X_INFO, "The file referenced, is *NOT* loaded\n");
+ pxf86Msg(X_INFO, "Loading %s/ati_drv.so\n", DRI_XORG_DRV_DIR);
+
+ /* we're failing to proxy software dri driver calls for certain xservers, so just make sure we're unloaded for now */
+ __driDriverExtensions[0] = NULL;
+ return;
+ }
+ }
+
+ if (!stubInit())
+ {
+ crDebug("vboxdriInitScreen: stubInit failed");
+ return;
+ }
+
+ /* Load swrast_dri.so to proxy dri related calls there. */
+ if (!vbox_load_sw_dri())
+ {
+ crDebug("vboxdriInitScreen: vbox_load_sw_dri failed...going to fail badly");
+ return;
+ }
+
+ /* Handle gl api.
+ * In the end application call would look like this:
+ * app call glFoo->(mesa asm dispatch stub)->cr_glFoo(vbox asm dispatch stub)->SPU Foo function(packspuFoo or alike)
+ * Note, we don't need to install extension functions via _glapi_add_dispatch, because we'd override glXGetProcAddress.
+ */
+ /* Mesa's dispatch table is different across library versions, have to modify mesa's table using offset info functions*/
+ vboxPatchMesaGLAPITable();
+
+ /* Handle glx api.
+ * In the end application call would look like this:
+ * app call glxFoo->(mesa asm dispatch stub patched with vbox_glXFoo:jmp glxim[Foo's index])->VBOXGLXTAG(glxFoo)
+ */
+ /* Fill structure used by our assembly stubs */
+ vboxFillGLXAPITable(&glxim);
+ /* Now patch functions exported by libGL.so */
+ vboxPatchMesaExports();
+}
+
+/*
+ * @todo we're missing first glx related call from the client application.
+ * Luckily, this doesn't add much problems, except for some cases.
+ */
+
+/* __DRIcoreExtension */
+
+static __DRIscreen *
+vboxdriCreateNewScreen(int screen, int fd, unsigned int sarea_handle,
+ const __DRIextension **extensions, const __DRIconfig ***driverConfigs,
+ void *loaderPrivate)
+{
+ (void) fd;
+ (void) sarea_handle;
+ SWDRI_SAFERET_SWRAST(createNewScreen, screen, extensions, driverConfigs, loaderPrivate);
+}
+
+static void
+vboxdriDestroyScreen(__DRIscreen *screen)
+{
+ SWDRI_SAFECALL_CORE(destroyScreen, screen);
+}
+
+static const __DRIextension **
+vboxdriGetExtensions(__DRIscreen *screen)
+{
+ SWDRI_SAFERET_CORE(getExtensions, screen);
+}
+
+static int
+vboxdriGetConfigAttrib(const __DRIconfig *config,
+ unsigned int attrib,
+ unsigned int *value)
+{
+ SWDRI_SAFERET_CORE(getConfigAttrib, config, attrib, value);
+}
+
+static int
+vboxdriIndexConfigAttrib(const __DRIconfig *config, int index,
+ unsigned int *attrib, unsigned int *value)
+{
+ SWDRI_SAFERET_CORE(indexConfigAttrib, config, index, attrib, value);
+}
+
+static __DRIdrawable *
+vboxdriCreateNewDrawable(__DRIscreen *screen,
+ const __DRIconfig *config,
+ unsigned int drawable_id,
+ unsigned int head,
+ void *loaderPrivate)
+{
+ (void) drawable_id;
+ (void) head;
+ SWDRI_SAFERET_SWRAST(createNewDrawable, screen, config, loaderPrivate);
+}
+
+static void
+vboxdriDestroyDrawable(__DRIdrawable *drawable)
+{
+ SWDRI_SAFECALL_CORE(destroyDrawable, drawable);
+}
+
+static void
+vboxdriSwapBuffers(__DRIdrawable *drawable)
+{
+ SWDRI_SAFECALL_CORE(swapBuffers, drawable);
+}
+
+static __DRIcontext *
+vboxdriCreateNewContext(__DRIscreen *screen,
+ const __DRIconfig *config,
+ __DRIcontext *shared,
+ void *loaderPrivate)
+{
+ SWDRI_SAFERET_CORE(createNewContext, screen, config, shared, loaderPrivate);
+}
+
+static int
+vboxdriCopyContext(__DRIcontext *dest,
+ __DRIcontext *src,
+ unsigned long mask)
+{
+ SWDRI_SAFERET_CORE(copyContext, dest, src, mask);
+}
+
+static void
+vboxdriDestroyContext(__DRIcontext *context)
+{
+ SWDRI_SAFECALL_CORE(destroyContext, context);
+}
+
+static int
+vboxdriBindContext(__DRIcontext *ctx,
+ __DRIdrawable *pdraw,
+ __DRIdrawable *pread)
+{
+ SWDRI_SAFERET_CORE(bindContext, ctx, pdraw, pread);
+}
+
+static int
+vboxdriUnbindContext(__DRIcontext *ctx)
+{
+ SWDRI_SAFERET_CORE(unbindContext, ctx)
+}
+
+/* __DRIlegacyExtension */
+
+static __DRIscreen *
+vboxdriCreateNewScreen_Legacy(int scrn,
+ const __DRIversion *ddx_version,
+ const __DRIversion *dri_version,
+ const __DRIversion *drm_version,
+ const __DRIframebuffer *frame_buffer,
+ drmAddress pSAREA, int fd,
+ const __DRIextension **extensions,
+ const __DRIconfig ***driver_modes,
+ void *loaderPrivate)
+{
+ (void) ddx_version;
+ (void) dri_version;
+ (void) frame_buffer;
+ (void) pSAREA;
+ (void) fd;
+ SWDRI_SAFERET_SWRAST(createNewScreen, scrn, extensions, driver_modes, loaderPrivate);
+}
+
+static __DRIdrawable *
+vboxdriCreateNewDrawable_Legacy(__DRIscreen *psp, const __DRIconfig *config,
+ drm_drawable_t hwDrawable, int renderType,
+ const int *attrs, void *data)
+{
+ (void) hwDrawable;
+ (void) renderType;
+ (void) attrs;
+ (void) data;
+ SWDRI_SAFERET_SWRAST(createNewDrawable, psp, config, data);
+}
+
+static __DRIcontext *
+vboxdriCreateNewContext_Legacy(__DRIscreen *psp, const __DRIconfig *config,
+ int render_type, __DRIcontext *shared,
+ drm_context_t hwContext, void *data)
+{
+ (void) render_type;
+ (void) hwContext;
+ return vboxdriCreateNewContext(psp, config, shared, data);
+}
+
+
+static const __DRIlegacyExtension vboxdriLegacyExtension = {
+ { __DRI_LEGACY, __DRI_LEGACY_VERSION },
+ vboxdriCreateNewScreen_Legacy,
+ vboxdriCreateNewDrawable_Legacy,
+ vboxdriCreateNewContext_Legacy
+};
+
+static const __DRIcoreExtension vboxdriCoreExtension = {
+ { __DRI_CORE, __DRI_CORE_VERSION },
+ vboxdriCreateNewScreen, /* driCreateNewScreen */
+ vboxdriDestroyScreen,
+ vboxdriGetExtensions,
+ vboxdriGetConfigAttrib,
+ vboxdriIndexConfigAttrib,
+ vboxdriCreateNewDrawable, /* driCreateNewDrawable */
+ vboxdriDestroyDrawable,
+ vboxdriSwapBuffers,
+ vboxdriCreateNewContext,
+ vboxdriCopyContext,
+ vboxdriDestroyContext,
+ vboxdriBindContext,
+ vboxdriUnbindContext
+};
+
+/* This structure is used by dri_util from mesa, don't rename it! */
+DECLEXPORT(const __DRIextension *) __driDriverExtensions[] = {
+ &vboxdriLegacyExtension.base,
+ &vboxdriCoreExtension.base,
+ NULL
+};
diff --git a/src/VBox/Additions/common/crOpenGL/fakedri_drv.h b/src/VBox/Additions/common/crOpenGL/fakedri_drv.h
new file mode 100644
index 00000000..5f77bd85
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/fakedri_drv.h
@@ -0,0 +1,123 @@
+/* $Id: fakedri_drv.h $ */
+/** @file
+ * VirtualBox guest OpenGL DRI header
+ */
+
+/*
+ * Copyright (C) 2009-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef GA_INCLUDED_SRC_common_crOpenGL_fakedri_drv_h
+#define GA_INCLUDED_SRC_common_crOpenGL_fakedri_drv_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "src/mesa/main/mtypes.h"
+#include "src/mesa/main/dd.h"
+#include "src/mesa/glapi/dispatch.h"
+#include "src/mesa/glapi/glapi.h"
+#include "src/mesa/glapi/glapitable.h"
+#include "src/mesa/glapi/glapioffsets.h"
+#include "src/mesa/drivers/dri/common/dri_util.h"
+#include "GL/internal/dri_interface.h"
+
+#include "glx_proto.h"
+
+#ifdef VBOX_OGL_GLX_USE_CSTUBS
+# include "dri_glx.h"
+#endif
+
+typedef struct _vbox_glxapi_table
+{
+ #define GLXAPI_ENTRY(Func) PGLXFUNC_##Func Func;
+ #include "fakedri_glxfuncsList.h"
+ #undef GLXAPI_ENTRY
+} fakedri_glxapi_table;
+
+extern fakedri_glxapi_table glxim;
+
+#ifdef VBOX_OGL_GLX_USE_CSTUBS
+/* Extern declarations for our C stubs */
+extern void VBOXGLXENTRYTAG(glXFreeMemoryMESA)(Display *dpy, int scrn, void *pointer) ;
+extern GLXContext VBOXGLXENTRYTAG(glXImportContextEXT)(Display *dpy, GLXContextID contextID) ;
+extern GLXContextID VBOXGLXENTRYTAG(glXGetContextIDEXT)(const GLXContext ctx) ;
+extern Bool VBOXGLXENTRYTAG(glXMakeCurrentReadSGI)(Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx) ;
+extern Display * VBOXGLXENTRYTAG(glXGetCurrentDisplayEXT)(void) ;
+extern void VBOXGLXENTRYTAG(glXFreeContextEXT)(Display *dpy, GLXContext ctx) ;
+extern int VBOXGLXENTRYTAG(glXQueryContextInfoEXT)(Display *dpy, GLXContext ctx) ;
+extern void * VBOXGLXENTRYTAG(glXAllocateMemoryMESA)(Display *dpy, int scrn,
+ size_t size, float readFreq,
+ float writeFreq, float priority);
+extern GLuint VBOXGLXENTRYTAG(glXGetMemoryOffsetMESA)(Display *dpy, int scrn, const void *pointer ) ;
+extern GLXPixmap VBOXGLXENTRYTAG(glXCreateGLXPixmapMESA)(Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap) ;
+extern void VBOXGLXENTRYTAG(glXCopyContext)( Display *dpy, GLXContext src, GLXContext dst, unsigned long mask);
+extern void VBOXGLXENTRYTAG(glXUseXFont)(Font font, int first, int count, int listBase) ;
+extern CR_GLXFuncPtr VBOXGLXENTRYTAG(glXGetProcAddress)(const GLubyte *name) ;
+extern Bool VBOXGLXENTRYTAG(glXQueryExtension)(Display *dpy, int *errorBase, int *eventBase) ;
+extern Bool VBOXGLXENTRYTAG(glXIsDirect)(Display *dpy, GLXContext ctx) ;
+extern GLXPixmap VBOXGLXENTRYTAG(glXCreateGLXPixmap)(Display *dpy, XVisualInfo *vis, Pixmap pixmap) ;
+extern void VBOXGLXENTRYTAG(glXSwapBuffers)(Display *dpy, GLXDrawable drawable) ;
+extern GLXDrawable VBOXGLXENTRYTAG(glXGetCurrentDrawable)(void) ;
+extern void VBOXGLXENTRYTAG(glXWaitGL)(void) ;
+extern Display * VBOXGLXENTRYTAG(glXGetCurrentDisplay)(void) ;
+extern const char * VBOXGLXENTRYTAG(glXQueryServerString)(Display *dpy, int screen, int name) ;
+extern GLXContext VBOXGLXENTRYTAG(glXCreateContext)(Display *dpy, XVisualInfo *vis, GLXContext share, Bool direct) ;
+extern int VBOXGLXENTRYTAG(glXGetConfig)(Display *dpy, XVisualInfo *vis, int attrib, int *value) ;
+extern void VBOXGLXENTRYTAG(glXWaitX)(void) ;
+extern GLXContext VBOXGLXENTRYTAG(glXGetCurrentContext)(void) ;
+extern const char * VBOXGLXENTRYTAG(glXGetClientString)(Display *dpy, int name) ;
+extern Bool VBOXGLXENTRYTAG(glXMakeCurrent)(Display *dpy, GLXDrawable drawable, GLXContext ctx) ;
+extern void VBOXGLXENTRYTAG(glXDestroyContext)(Display *dpy, GLXContext ctx) ;
+extern CR_GLXFuncPtr VBOXGLXENTRYTAG(glXGetProcAddressARB)(const GLubyte *name) ;
+extern void VBOXGLXENTRYTAG(glXDestroyGLXPixmap)(Display *dpy, GLXPixmap pix) ;
+extern Bool VBOXGLXENTRYTAG(glXQueryVersion)(Display *dpy, int *major, int *minor) ;
+extern XVisualInfo * VBOXGLXENTRYTAG(glXChooseVisual)(Display *dpy, int screen, int *attribList) ;
+extern const char * VBOXGLXENTRYTAG(glXQueryExtensionsString)(Display *dpy, int screen) ;
+extern GLXPbufferSGIX VBOXGLXENTRYTAG(glXCreateGLXPbufferSGIX)(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list);
+extern int VBOXGLXENTRYTAG(glXQueryGLXPbufferSGIX)(Display *dpy, GLXPbuffer pbuf, int attribute, unsigned int *value);
+extern GLXFBConfigSGIX * VBOXGLXENTRYTAG(glXChooseFBConfigSGIX)(Display *dpy, int screen, int *attrib_list, int *nelements);
+extern void VBOXGLXENTRYTAG(glXDestroyGLXPbufferSGIX)(Display *dpy, GLXPbuffer pbuf) ;
+extern void VBOXGLXENTRYTAG(glXSelectEventSGIX)(Display *dpy, GLXDrawable drawable, unsigned long mask) ;
+extern void VBOXGLXENTRYTAG(glXGetSelectedEventSGIX)(Display *dpy, GLXDrawable drawable, unsigned long *mask) ;
+extern GLXFBConfigSGIX VBOXGLXENTRYTAG(glXGetFBConfigFromVisualSGIX)(Display *dpy, XVisualInfo *vis) ;
+extern XVisualInfo * VBOXGLXENTRYTAG(glXGetVisualFromFBConfigSGIX)(Display *dpy, GLXFBConfig config) ;
+extern GLXContext VBOXGLXENTRYTAG(glXCreateContextWithConfigSGIX)(Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
+extern GLXPixmap VBOXGLXENTRYTAG(glXCreateGLXPixmapWithConfigSGIX)(Display *dpy, GLXFBConfig config, Pixmap pixmap) ;
+extern int VBOXGLXENTRYTAG(glXGetFBConfigAttribSGIX)(Display *dpy, GLXFBConfig config, int attribute, int *value) ;
+extern GLXFBConfig * VBOXGLXENTRYTAG(glXChooseFBConfig)(Display *dpy, int screen, ATTRIB_TYPE *attrib_list, int *nelements) ;
+extern GLXPbuffer VBOXGLXENTRYTAG(glXCreatePbuffer)(Display *dpy, GLXFBConfig config, ATTRIB_TYPE *attrib_list) ;
+extern GLXPixmap VBOXGLXENTRYTAG(glXCreatePixmap)(Display *dpy, GLXFBConfig config, Pixmap pixmap, const ATTRIB_TYPE *attrib_list) ;
+extern GLXWindow VBOXGLXENTRYTAG(glXCreateWindow)(Display *dpy, GLXFBConfig config, Window win, ATTRIB_TYPE *attrib_list) ;
+extern GLXContext VBOXGLXENTRYTAG(glXCreateNewContext)(Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
+extern void VBOXGLXENTRYTAG(glXDestroyPbuffer)(Display *dpy, GLXPbuffer pbuf) ;
+extern void VBOXGLXENTRYTAG(glXDestroyPixmap)(Display *dpy, GLXPixmap pixmap) ;
+extern void VBOXGLXENTRYTAG(glXDestroyWindow)(Display *dpy, GLXWindow win) ;
+extern GLXDrawable VBOXGLXENTRYTAG(glXGetCurrentReadDrawable)(void) ;
+extern int VBOXGLXENTRYTAG(glXGetFBConfigAttrib)(Display *dpy, GLXFBConfig config, int attribute, int *value) ;
+extern GLXFBConfig * VBOXGLXENTRYTAG(glXGetFBConfigs)(Display *dpy, int screen, int *nelements) ;
+extern void VBOXGLXENTRYTAG(glXGetSelectedEvent)(Display *dpy, GLXDrawable draw, unsigned long *event_mask) ;
+extern XVisualInfo * VBOXGLXENTRYTAG(glXGetVisualFromFBConfig)(Display *dpy, GLXFBConfig config) ;
+extern Bool VBOXGLXENTRYTAG(glXMakeContextCurrent)(Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx) ;
+extern int VBOXGLXENTRYTAG(glXQueryContext)(Display *dpy, GLXContext ctx, int attribute, int *value) ;
+extern void VBOXGLXENTRYTAG(glXQueryDrawable)(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value) ;
+extern void VBOXGLXENTRYTAG(glXSelectEvent)(Display *dpy, GLXDrawable draw, unsigned long event_mask) ;
+#else
+/* Extern declarations for our asm stubs */
+# define GLXAPI_ENTRY(Func) \
+ extern void vbox_glX##Func;\
+ extern void vbox_glX##Func##_EndProc;
+# include "fakedri_glxfuncsList.h"
+# undef GLXAPI_ENTRY
+#endif
+
+#endif /* !GA_INCLUDED_SRC_common_crOpenGL_fakedri_drv_h */
+
diff --git a/src/VBox/Additions/common/crOpenGL/fakedri_glfuncsList.h b/src/VBox/Additions/common/crOpenGL/fakedri_glfuncsList.h
new file mode 100644
index 00000000..6928a2ab
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/fakedri_glfuncsList.h
@@ -0,0 +1,730 @@
+/* $Id: fakedri_glfuncsList.h $ */
+/** @file
+ * VBox OpenGL list of opengl functions common in Mesa and vbox opengl stub
+ */
+
+/*
+ * Copyright (C) 2009-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef GLAPI_ENTRY
+#error GLAPI_ENTRY should be defined.
+#endif
+
+GLAPI_ENTRY(NewList)
+GLAPI_ENTRY(EndList)
+GLAPI_ENTRY(CallList)
+GLAPI_ENTRY(CallLists)
+GLAPI_ENTRY(DeleteLists)
+GLAPI_ENTRY(GenLists)
+GLAPI_ENTRY(ListBase)
+GLAPI_ENTRY(Begin)
+GLAPI_ENTRY(Bitmap)
+GLAPI_ENTRY(Color3b)
+GLAPI_ENTRY(Color3bv)
+GLAPI_ENTRY(Color3d)
+GLAPI_ENTRY(Color3dv)
+GLAPI_ENTRY(Color3f)
+GLAPI_ENTRY(Color3fv)
+GLAPI_ENTRY(Color3i)
+GLAPI_ENTRY(Color3iv)
+GLAPI_ENTRY(Color3s)
+GLAPI_ENTRY(Color3sv)
+GLAPI_ENTRY(Color3ub)
+GLAPI_ENTRY(Color3ubv)
+GLAPI_ENTRY(Color3ui)
+GLAPI_ENTRY(Color3uiv)
+GLAPI_ENTRY(Color3us)
+GLAPI_ENTRY(Color3usv)
+GLAPI_ENTRY(Color4b)
+GLAPI_ENTRY(Color4bv)
+GLAPI_ENTRY(Color4d)
+GLAPI_ENTRY(Color4dv)
+GLAPI_ENTRY(Color4f)
+GLAPI_ENTRY(Color4fv)
+GLAPI_ENTRY(Color4i)
+GLAPI_ENTRY(Color4iv)
+GLAPI_ENTRY(Color4s)
+GLAPI_ENTRY(Color4sv)
+GLAPI_ENTRY(Color4ub)
+GLAPI_ENTRY(Color4ubv)
+GLAPI_ENTRY(Color4ui)
+GLAPI_ENTRY(Color4uiv)
+GLAPI_ENTRY(Color4us)
+GLAPI_ENTRY(Color4usv)
+GLAPI_ENTRY(EdgeFlag)
+GLAPI_ENTRY(EdgeFlagv)
+GLAPI_ENTRY(End)
+GLAPI_ENTRY(Indexd)
+GLAPI_ENTRY(Indexdv)
+GLAPI_ENTRY(Indexf)
+GLAPI_ENTRY(Indexfv)
+GLAPI_ENTRY(Indexi)
+GLAPI_ENTRY(Indexiv)
+GLAPI_ENTRY(Indexs)
+GLAPI_ENTRY(Indexsv)
+GLAPI_ENTRY(Normal3b)
+GLAPI_ENTRY(Normal3bv)
+GLAPI_ENTRY(Normal3d)
+GLAPI_ENTRY(Normal3dv)
+GLAPI_ENTRY(Normal3f)
+GLAPI_ENTRY(Normal3fv)
+GLAPI_ENTRY(Normal3i)
+GLAPI_ENTRY(Normal3iv)
+GLAPI_ENTRY(Normal3s)
+GLAPI_ENTRY(Normal3sv)
+GLAPI_ENTRY(RasterPos2d)
+GLAPI_ENTRY(RasterPos2dv)
+GLAPI_ENTRY(RasterPos2f)
+GLAPI_ENTRY(RasterPos2fv)
+GLAPI_ENTRY(RasterPos2i)
+GLAPI_ENTRY(RasterPos2iv)
+GLAPI_ENTRY(RasterPos2s)
+GLAPI_ENTRY(RasterPos2sv)
+GLAPI_ENTRY(RasterPos3d)
+GLAPI_ENTRY(RasterPos3dv)
+GLAPI_ENTRY(RasterPos3f)
+GLAPI_ENTRY(RasterPos3fv)
+GLAPI_ENTRY(RasterPos3i)
+GLAPI_ENTRY(RasterPos3iv)
+GLAPI_ENTRY(RasterPos3s)
+GLAPI_ENTRY(RasterPos3sv)
+GLAPI_ENTRY(RasterPos4d)
+GLAPI_ENTRY(RasterPos4dv)
+GLAPI_ENTRY(RasterPos4f)
+GLAPI_ENTRY(RasterPos4fv)
+GLAPI_ENTRY(RasterPos4i)
+GLAPI_ENTRY(RasterPos4iv)
+GLAPI_ENTRY(RasterPos4s)
+GLAPI_ENTRY(RasterPos4sv)
+GLAPI_ENTRY(Rectd)
+GLAPI_ENTRY(Rectdv)
+GLAPI_ENTRY(Rectf)
+GLAPI_ENTRY(Rectfv)
+GLAPI_ENTRY(Recti)
+GLAPI_ENTRY(Rectiv)
+GLAPI_ENTRY(Rects)
+GLAPI_ENTRY(Rectsv)
+GLAPI_ENTRY(TexCoord1d)
+GLAPI_ENTRY(TexCoord1dv)
+GLAPI_ENTRY(TexCoord1f)
+GLAPI_ENTRY(TexCoord1fv)
+GLAPI_ENTRY(TexCoord1i)
+GLAPI_ENTRY(TexCoord1iv)
+GLAPI_ENTRY(TexCoord1s)
+GLAPI_ENTRY(TexCoord1sv)
+GLAPI_ENTRY(TexCoord2d)
+GLAPI_ENTRY(TexCoord2dv)
+GLAPI_ENTRY(TexCoord2f)
+GLAPI_ENTRY(TexCoord2fv)
+GLAPI_ENTRY(TexCoord2i)
+GLAPI_ENTRY(TexCoord2iv)
+GLAPI_ENTRY(TexCoord2s)
+GLAPI_ENTRY(TexCoord2sv)
+GLAPI_ENTRY(TexCoord3d)
+GLAPI_ENTRY(TexCoord3dv)
+GLAPI_ENTRY(TexCoord3f)
+GLAPI_ENTRY(TexCoord3fv)
+GLAPI_ENTRY(TexCoord3i)
+GLAPI_ENTRY(TexCoord3iv)
+GLAPI_ENTRY(TexCoord3s)
+GLAPI_ENTRY(TexCoord3sv)
+GLAPI_ENTRY(TexCoord4d)
+GLAPI_ENTRY(TexCoord4dv)
+GLAPI_ENTRY(TexCoord4f)
+GLAPI_ENTRY(TexCoord4fv)
+GLAPI_ENTRY(TexCoord4i)
+GLAPI_ENTRY(TexCoord4iv)
+GLAPI_ENTRY(TexCoord4s)
+GLAPI_ENTRY(TexCoord4sv)
+GLAPI_ENTRY(Vertex2d)
+GLAPI_ENTRY(Vertex2dv)
+GLAPI_ENTRY(Vertex2f)
+GLAPI_ENTRY(Vertex2fv)
+GLAPI_ENTRY(Vertex2i)
+GLAPI_ENTRY(Vertex2iv)
+GLAPI_ENTRY(Vertex2s)
+GLAPI_ENTRY(Vertex2sv)
+GLAPI_ENTRY(Vertex3d)
+GLAPI_ENTRY(Vertex3dv)
+GLAPI_ENTRY(Vertex3f)
+GLAPI_ENTRY(Vertex3fv)
+GLAPI_ENTRY(Vertex3i)
+GLAPI_ENTRY(Vertex3iv)
+GLAPI_ENTRY(Vertex3s)
+GLAPI_ENTRY(Vertex3sv)
+GLAPI_ENTRY(Vertex4d)
+GLAPI_ENTRY(Vertex4dv)
+GLAPI_ENTRY(Vertex4f)
+GLAPI_ENTRY(Vertex4fv)
+GLAPI_ENTRY(Vertex4i)
+GLAPI_ENTRY(Vertex4iv)
+GLAPI_ENTRY(Vertex4s)
+GLAPI_ENTRY(Vertex4sv)
+GLAPI_ENTRY(ClipPlane)
+GLAPI_ENTRY(ColorMaterial)
+GLAPI_ENTRY(CullFace)
+GLAPI_ENTRY(Fogf)
+GLAPI_ENTRY(Fogfv)
+GLAPI_ENTRY(Fogi)
+GLAPI_ENTRY(Fogiv)
+GLAPI_ENTRY(FrontFace)
+GLAPI_ENTRY(Hint)
+GLAPI_ENTRY(Lightf)
+GLAPI_ENTRY(Lightfv)
+GLAPI_ENTRY(Lighti)
+GLAPI_ENTRY(Lightiv)
+GLAPI_ENTRY(LightModelf)
+GLAPI_ENTRY(LightModelfv)
+GLAPI_ENTRY(LightModeli)
+GLAPI_ENTRY(LightModeliv)
+GLAPI_ENTRY(LineStipple)
+GLAPI_ENTRY(LineWidth)
+GLAPI_ENTRY(Materialf)
+GLAPI_ENTRY(Materialfv)
+GLAPI_ENTRY(Materiali)
+GLAPI_ENTRY(Materialiv)
+GLAPI_ENTRY(PointSize)
+GLAPI_ENTRY(PolygonMode)
+GLAPI_ENTRY(PolygonStipple)
+GLAPI_ENTRY(Scissor)
+GLAPI_ENTRY(ShadeModel)
+GLAPI_ENTRY(TexParameterf)
+GLAPI_ENTRY(TexParameterfv)
+GLAPI_ENTRY(TexParameteri)
+GLAPI_ENTRY(TexParameteriv)
+GLAPI_ENTRY(TexImage1D)
+GLAPI_ENTRY(TexImage2D)
+GLAPI_ENTRY(TexEnvf)
+GLAPI_ENTRY(TexEnvfv)
+GLAPI_ENTRY(TexEnvi)
+GLAPI_ENTRY(TexEnviv)
+GLAPI_ENTRY(TexGend)
+GLAPI_ENTRY(TexGendv)
+GLAPI_ENTRY(TexGenf)
+GLAPI_ENTRY(TexGenfv)
+GLAPI_ENTRY(TexGeni)
+GLAPI_ENTRY(TexGeniv)
+GLAPI_ENTRY(FeedbackBuffer)
+GLAPI_ENTRY(SelectBuffer)
+GLAPI_ENTRY(RenderMode)
+GLAPI_ENTRY(InitNames)
+GLAPI_ENTRY(LoadName)
+GLAPI_ENTRY(PassThrough)
+GLAPI_ENTRY(PopName)
+GLAPI_ENTRY(PushName)
+GLAPI_ENTRY(DrawBuffer)
+GLAPI_ENTRY(Clear)
+GLAPI_ENTRY(ClearAccum)
+GLAPI_ENTRY(ClearIndex)
+GLAPI_ENTRY(ClearColor)
+GLAPI_ENTRY(ClearStencil)
+GLAPI_ENTRY(ClearDepth)
+GLAPI_ENTRY(StencilMask)
+GLAPI_ENTRY(ColorMask)
+GLAPI_ENTRY(DepthMask)
+GLAPI_ENTRY(IndexMask)
+GLAPI_ENTRY(Accum)
+GLAPI_ENTRY(Disable)
+GLAPI_ENTRY(Enable)
+GLAPI_ENTRY(Finish)
+GLAPI_ENTRY(Flush)
+GLAPI_ENTRY(PopAttrib)
+GLAPI_ENTRY(PushAttrib)
+GLAPI_ENTRY(Map1d)
+GLAPI_ENTRY(Map1f)
+GLAPI_ENTRY(Map2d)
+GLAPI_ENTRY(Map2f)
+GLAPI_ENTRY(MapGrid1d)
+GLAPI_ENTRY(MapGrid1f)
+GLAPI_ENTRY(MapGrid2d)
+GLAPI_ENTRY(MapGrid2f)
+GLAPI_ENTRY(EvalCoord1d)
+GLAPI_ENTRY(EvalCoord1dv)
+GLAPI_ENTRY(EvalCoord1f)
+GLAPI_ENTRY(EvalCoord1fv)
+GLAPI_ENTRY(EvalCoord2d)
+GLAPI_ENTRY(EvalCoord2dv)
+GLAPI_ENTRY(EvalCoord2f)
+GLAPI_ENTRY(EvalCoord2fv)
+GLAPI_ENTRY(EvalMesh1)
+GLAPI_ENTRY(EvalPoint1)
+GLAPI_ENTRY(EvalMesh2)
+GLAPI_ENTRY(EvalPoint2)
+GLAPI_ENTRY(AlphaFunc)
+GLAPI_ENTRY(BlendFunc)
+GLAPI_ENTRY(LogicOp)
+GLAPI_ENTRY(StencilFunc)
+GLAPI_ENTRY(StencilOp)
+GLAPI_ENTRY(DepthFunc)
+GLAPI_ENTRY(PixelZoom)
+GLAPI_ENTRY(PixelTransferf)
+GLAPI_ENTRY(PixelTransferi)
+GLAPI_ENTRY(PixelStoref)
+GLAPI_ENTRY(PixelStorei)
+GLAPI_ENTRY(PixelMapfv)
+GLAPI_ENTRY(PixelMapuiv)
+GLAPI_ENTRY(PixelMapusv)
+GLAPI_ENTRY(ReadBuffer)
+GLAPI_ENTRY(CopyPixels)
+GLAPI_ENTRY(ReadPixels)
+GLAPI_ENTRY(DrawPixels)
+GLAPI_ENTRY(GetBooleanv)
+GLAPI_ENTRY(GetClipPlane)
+GLAPI_ENTRY(GetDoublev)
+GLAPI_ENTRY(GetError)
+GLAPI_ENTRY(GetFloatv)
+GLAPI_ENTRY(GetIntegerv)
+GLAPI_ENTRY(GetLightfv)
+GLAPI_ENTRY(GetLightiv)
+GLAPI_ENTRY(GetMapdv)
+GLAPI_ENTRY(GetMapfv)
+GLAPI_ENTRY(GetMapiv)
+GLAPI_ENTRY(GetMaterialfv)
+GLAPI_ENTRY(GetMaterialiv)
+GLAPI_ENTRY(GetPixelMapfv)
+GLAPI_ENTRY(GetPixelMapuiv)
+GLAPI_ENTRY(GetPixelMapusv)
+GLAPI_ENTRY(GetPolygonStipple)
+GLAPI_ENTRY(GetString)
+GLAPI_ENTRY(GetTexEnvfv)
+GLAPI_ENTRY(GetTexEnviv)
+GLAPI_ENTRY(GetTexGendv)
+GLAPI_ENTRY(GetTexGenfv)
+GLAPI_ENTRY(GetTexGeniv)
+GLAPI_ENTRY(GetTexImage)
+GLAPI_ENTRY(GetTexParameterfv)
+GLAPI_ENTRY(GetTexParameteriv)
+GLAPI_ENTRY(GetTexLevelParameterfv)
+GLAPI_ENTRY(GetTexLevelParameteriv)
+GLAPI_ENTRY(IsEnabled)
+GLAPI_ENTRY(IsList)
+GLAPI_ENTRY(DepthRange)
+GLAPI_ENTRY(Frustum)
+GLAPI_ENTRY(LoadIdentity)
+GLAPI_ENTRY(LoadMatrixf)
+GLAPI_ENTRY(LoadMatrixd)
+GLAPI_ENTRY(MatrixMode)
+GLAPI_ENTRY(MultMatrixf)
+GLAPI_ENTRY(MultMatrixd)
+GLAPI_ENTRY(Ortho)
+GLAPI_ENTRY(PopMatrix)
+GLAPI_ENTRY(PushMatrix)
+GLAPI_ENTRY(Rotated)
+GLAPI_ENTRY(Rotatef)
+GLAPI_ENTRY(Scaled)
+GLAPI_ENTRY(Scalef)
+GLAPI_ENTRY(Translated)
+GLAPI_ENTRY(Translatef)
+GLAPI_ENTRY(Viewport)
+GLAPI_ENTRY(ArrayElement)
+GLAPI_ENTRY(BindTexture)
+GLAPI_ENTRY(ColorPointer)
+GLAPI_ENTRY(DisableClientState)
+GLAPI_ENTRY(DrawArrays)
+GLAPI_ENTRY(DrawElements)
+GLAPI_ENTRY(EdgeFlagPointer)
+GLAPI_ENTRY(EnableClientState)
+GLAPI_ENTRY(IndexPointer)
+GLAPI_ENTRY(Indexub)
+GLAPI_ENTRY(Indexubv)
+GLAPI_ENTRY(InterleavedArrays)
+GLAPI_ENTRY(NormalPointer)
+GLAPI_ENTRY(PolygonOffset)
+GLAPI_ENTRY(TexCoordPointer)
+GLAPI_ENTRY(VertexPointer)
+GLAPI_ENTRY(AreTexturesResident)
+GLAPI_ENTRY(CopyTexImage1D)
+GLAPI_ENTRY(CopyTexImage2D)
+GLAPI_ENTRY(CopyTexSubImage1D)
+GLAPI_ENTRY(CopyTexSubImage2D)
+GLAPI_ENTRY(DeleteTextures)
+GLAPI_ENTRY(GenTextures)
+GLAPI_ENTRY(GetPointerv)
+GLAPI_ENTRY(IsTexture)
+GLAPI_ENTRY(PrioritizeTextures)
+GLAPI_ENTRY(TexSubImage1D)
+GLAPI_ENTRY(TexSubImage2D)
+GLAPI_ENTRY(PopClientAttrib)
+GLAPI_ENTRY(PushClientAttrib)
+GLAPI_ENTRY(BlendColor)
+GLAPI_ENTRY(BlendEquation)
+GLAPI_ENTRY(DrawRangeElements)
+GLAPI_ENTRY(ColorTable)
+GLAPI_ENTRY(ColorTableParameterfv)
+GLAPI_ENTRY(ColorTableParameteriv)
+GLAPI_ENTRY(CopyColorTable)
+GLAPI_ENTRY(GetColorTable)
+GLAPI_ENTRY(GetColorTableParameterfv)
+GLAPI_ENTRY(GetColorTableParameteriv)
+GLAPI_ENTRY(ColorSubTable)
+GLAPI_ENTRY(CopyColorSubTable)
+GLAPI_ENTRY(ConvolutionFilter1D)
+GLAPI_ENTRY(ConvolutionFilter2D)
+GLAPI_ENTRY(ConvolutionParameterf)
+GLAPI_ENTRY(ConvolutionParameterfv)
+GLAPI_ENTRY(ConvolutionParameteri)
+GLAPI_ENTRY(ConvolutionParameteriv)
+GLAPI_ENTRY(CopyConvolutionFilter1D)
+GLAPI_ENTRY(CopyConvolutionFilter2D)
+GLAPI_ENTRY(GetConvolutionFilter)
+GLAPI_ENTRY(GetConvolutionParameterfv)
+GLAPI_ENTRY(GetConvolutionParameteriv)
+GLAPI_ENTRY(GetSeparableFilter)
+GLAPI_ENTRY(SeparableFilter2D)
+GLAPI_ENTRY(GetHistogram)
+GLAPI_ENTRY(GetHistogramParameterfv)
+GLAPI_ENTRY(GetHistogramParameteriv)
+GLAPI_ENTRY(GetMinmax)
+GLAPI_ENTRY(GetMinmaxParameterfv)
+GLAPI_ENTRY(GetMinmaxParameteriv)
+GLAPI_ENTRY(Histogram)
+GLAPI_ENTRY(Minmax)
+GLAPI_ENTRY(ResetHistogram)
+GLAPI_ENTRY(ResetMinmax)
+GLAPI_ENTRY(TexImage3D)
+GLAPI_ENTRY(TexSubImage3D)
+GLAPI_ENTRY(CopyTexSubImage3D)
+GLAPI_ENTRY(ActiveTextureARB)
+GLAPI_ENTRY(ClientActiveTextureARB)
+GLAPI_ENTRY(MultiTexCoord1dARB)
+GLAPI_ENTRY(MultiTexCoord1dvARB)
+GLAPI_ENTRY(MultiTexCoord1fARB)
+GLAPI_ENTRY(MultiTexCoord1fvARB)
+GLAPI_ENTRY(MultiTexCoord1iARB)
+GLAPI_ENTRY(MultiTexCoord1ivARB)
+GLAPI_ENTRY(MultiTexCoord1sARB)
+GLAPI_ENTRY(MultiTexCoord1svARB)
+GLAPI_ENTRY(MultiTexCoord2dARB)
+GLAPI_ENTRY(MultiTexCoord2dvARB)
+GLAPI_ENTRY(MultiTexCoord2fARB)
+GLAPI_ENTRY(MultiTexCoord2fvARB)
+GLAPI_ENTRY(MultiTexCoord2iARB)
+GLAPI_ENTRY(MultiTexCoord2ivARB)
+GLAPI_ENTRY(MultiTexCoord2sARB)
+GLAPI_ENTRY(MultiTexCoord2svARB)
+GLAPI_ENTRY(MultiTexCoord3dARB)
+GLAPI_ENTRY(MultiTexCoord3dvARB)
+GLAPI_ENTRY(MultiTexCoord3fARB)
+GLAPI_ENTRY(MultiTexCoord3fvARB)
+GLAPI_ENTRY(MultiTexCoord3iARB)
+GLAPI_ENTRY(MultiTexCoord3ivARB)
+GLAPI_ENTRY(MultiTexCoord3sARB)
+GLAPI_ENTRY(MultiTexCoord3svARB)
+GLAPI_ENTRY(MultiTexCoord4dARB)
+GLAPI_ENTRY(MultiTexCoord4dvARB)
+GLAPI_ENTRY(MultiTexCoord4fARB)
+GLAPI_ENTRY(MultiTexCoord4fvARB)
+GLAPI_ENTRY(MultiTexCoord4iARB)
+GLAPI_ENTRY(MultiTexCoord4ivARB)
+GLAPI_ENTRY(MultiTexCoord4sARB)
+GLAPI_ENTRY(MultiTexCoord4svARB)
+GLAPI_ENTRY(AttachShader)
+GLAPI_ENTRY(CreateProgram)
+GLAPI_ENTRY(CreateShader)
+GLAPI_ENTRY(DeleteProgram)
+GLAPI_ENTRY(DeleteShader)
+GLAPI_ENTRY(DetachShader)
+GLAPI_ENTRY(GetAttachedShaders)
+GLAPI_ENTRY(GetProgramInfoLog)
+GLAPI_ENTRY(GetProgramiv)
+GLAPI_ENTRY(GetShaderInfoLog)
+GLAPI_ENTRY(GetShaderiv)
+GLAPI_ENTRY(IsProgram)
+GLAPI_ENTRY(IsShader)
+GLAPI_ENTRY(StencilFuncSeparate)
+GLAPI_ENTRY(StencilMaskSeparate)
+GLAPI_ENTRY(StencilOpSeparate)
+GLAPI_ENTRY(UniformMatrix2x3fv)
+GLAPI_ENTRY(UniformMatrix2x4fv)
+GLAPI_ENTRY(UniformMatrix3x2fv)
+GLAPI_ENTRY(UniformMatrix3x4fv)
+GLAPI_ENTRY(UniformMatrix4x2fv)
+GLAPI_ENTRY(UniformMatrix4x3fv)
+GLAPI_ENTRY(LoadTransposeMatrixdARB)
+GLAPI_ENTRY(LoadTransposeMatrixfARB)
+GLAPI_ENTRY(MultTransposeMatrixdARB)
+GLAPI_ENTRY(MultTransposeMatrixfARB)
+GLAPI_ENTRY(SampleCoverageARB)
+GLAPI_ENTRY(CompressedTexImage1DARB)
+GLAPI_ENTRY(CompressedTexImage2DARB)
+GLAPI_ENTRY(CompressedTexImage3DARB)
+GLAPI_ENTRY(CompressedTexSubImage1DARB)
+GLAPI_ENTRY(CompressedTexSubImage2DARB)
+GLAPI_ENTRY(CompressedTexSubImage3DARB)
+GLAPI_ENTRY(GetCompressedTexImageARB)
+GLAPI_ENTRY(DisableVertexAttribArrayARB)
+GLAPI_ENTRY(EnableVertexAttribArrayARB)
+GLAPI_ENTRY(GetProgramEnvParameterdvARB)
+GLAPI_ENTRY(GetProgramEnvParameterfvARB)
+GLAPI_ENTRY(GetProgramLocalParameterdvARB)
+GLAPI_ENTRY(GetProgramLocalParameterfvARB)
+GLAPI_ENTRY(GetProgramStringARB)
+GLAPI_ENTRY(GetProgramivARB)
+GLAPI_ENTRY(GetVertexAttribdvARB)
+GLAPI_ENTRY(GetVertexAttribfvARB)
+GLAPI_ENTRY(GetVertexAttribivARB)
+GLAPI_ENTRY(ProgramEnvParameter4dARB)
+GLAPI_ENTRY(ProgramEnvParameter4dvARB)
+GLAPI_ENTRY(ProgramEnvParameter4fARB)
+GLAPI_ENTRY(ProgramEnvParameter4fvARB)
+GLAPI_ENTRY(ProgramLocalParameter4dARB)
+GLAPI_ENTRY(ProgramLocalParameter4dvARB)
+GLAPI_ENTRY(ProgramLocalParameter4fARB)
+GLAPI_ENTRY(ProgramLocalParameter4fvARB)
+GLAPI_ENTRY(ProgramStringARB)
+GLAPI_ENTRY(VertexAttrib1dARB)
+GLAPI_ENTRY(VertexAttrib1dvARB)
+GLAPI_ENTRY(VertexAttrib1fARB)
+GLAPI_ENTRY(VertexAttrib1fvARB)
+GLAPI_ENTRY(VertexAttrib1sARB)
+GLAPI_ENTRY(VertexAttrib1svARB)
+GLAPI_ENTRY(VertexAttrib2dARB)
+GLAPI_ENTRY(VertexAttrib2dvARB)
+GLAPI_ENTRY(VertexAttrib2fARB)
+GLAPI_ENTRY(VertexAttrib2fvARB)
+GLAPI_ENTRY(VertexAttrib2sARB)
+GLAPI_ENTRY(VertexAttrib2svARB)
+GLAPI_ENTRY(VertexAttrib3dARB)
+GLAPI_ENTRY(VertexAttrib3dvARB)
+GLAPI_ENTRY(VertexAttrib3fARB)
+GLAPI_ENTRY(VertexAttrib3fvARB)
+GLAPI_ENTRY(VertexAttrib3sARB)
+GLAPI_ENTRY(VertexAttrib3svARB)
+GLAPI_ENTRY(VertexAttrib4NbvARB)
+GLAPI_ENTRY(VertexAttrib4NivARB)
+GLAPI_ENTRY(VertexAttrib4NsvARB)
+GLAPI_ENTRY(VertexAttrib4NubARB)
+GLAPI_ENTRY(VertexAttrib4NubvARB)
+GLAPI_ENTRY(VertexAttrib4NuivARB)
+GLAPI_ENTRY(VertexAttrib4NusvARB)
+GLAPI_ENTRY(VertexAttrib4bvARB)
+GLAPI_ENTRY(VertexAttrib4dARB)
+GLAPI_ENTRY(VertexAttrib4dvARB)
+GLAPI_ENTRY(VertexAttrib4fARB)
+GLAPI_ENTRY(VertexAttrib4fvARB)
+GLAPI_ENTRY(VertexAttrib4ivARB)
+GLAPI_ENTRY(VertexAttrib4sARB)
+GLAPI_ENTRY(VertexAttrib4svARB)
+GLAPI_ENTRY(VertexAttrib4ubvARB)
+GLAPI_ENTRY(VertexAttrib4uivARB)
+GLAPI_ENTRY(VertexAttrib4usvARB)
+GLAPI_ENTRY(VertexAttribPointerARB)
+GLAPI_ENTRY(BindBufferARB)
+GLAPI_ENTRY(BufferDataARB)
+GLAPI_ENTRY(BufferSubDataARB)
+GLAPI_ENTRY(DeleteBuffersARB)
+GLAPI_ENTRY(GenBuffersARB)
+GLAPI_ENTRY(GetBufferParameterivARB)
+GLAPI_ENTRY(GetBufferPointervARB)
+GLAPI_ENTRY(GetBufferSubDataARB)
+GLAPI_ENTRY(IsBufferARB)
+GLAPI_ENTRY(MapBufferARB)
+GLAPI_ENTRY(UnmapBufferARB)
+GLAPI_ENTRY(BeginQueryARB)
+GLAPI_ENTRY(DeleteQueriesARB)
+GLAPI_ENTRY(EndQueryARB)
+GLAPI_ENTRY(GenQueriesARB)
+GLAPI_ENTRY(GetQueryObjectivARB)
+GLAPI_ENTRY(GetQueryObjectuivARB)
+GLAPI_ENTRY(GetQueryivARB)
+GLAPI_ENTRY(IsQueryARB)
+GLAPI_ENTRY(AttachObjectARB)
+GLAPI_ENTRY(CompileShaderARB)
+GLAPI_ENTRY(CreateProgramObjectARB)
+GLAPI_ENTRY(CreateShaderObjectARB)
+GLAPI_ENTRY(DeleteObjectARB)
+GLAPI_ENTRY(DetachObjectARB)
+GLAPI_ENTRY(GetActiveUniformARB)
+GLAPI_ENTRY(GetAttachedObjectsARB)
+GLAPI_ENTRY(GetHandleARB)
+GLAPI_ENTRY(GetInfoLogARB)
+GLAPI_ENTRY(GetObjectParameterfvARB)
+GLAPI_ENTRY(GetObjectParameterivARB)
+GLAPI_ENTRY(GetShaderSourceARB)
+GLAPI_ENTRY(GetUniformLocationARB)
+GLAPI_ENTRY(GetUniformfvARB)
+GLAPI_ENTRY(GetUniformivARB)
+GLAPI_ENTRY(LinkProgramARB)
+GLAPI_ENTRY(ShaderSourceARB)
+GLAPI_ENTRY(Uniform1fARB)
+GLAPI_ENTRY(Uniform1fvARB)
+GLAPI_ENTRY(Uniform1iARB)
+GLAPI_ENTRY(Uniform1ivARB)
+GLAPI_ENTRY(Uniform2fARB)
+GLAPI_ENTRY(Uniform2fvARB)
+GLAPI_ENTRY(Uniform2iARB)
+GLAPI_ENTRY(Uniform2ivARB)
+GLAPI_ENTRY(Uniform3fARB)
+GLAPI_ENTRY(Uniform3fvARB)
+GLAPI_ENTRY(Uniform3iARB)
+GLAPI_ENTRY(Uniform3ivARB)
+GLAPI_ENTRY(Uniform4fARB)
+GLAPI_ENTRY(Uniform4fvARB)
+GLAPI_ENTRY(Uniform4iARB)
+GLAPI_ENTRY(Uniform4ivARB)
+GLAPI_ENTRY(UniformMatrix2fvARB)
+GLAPI_ENTRY(UniformMatrix3fvARB)
+GLAPI_ENTRY(UniformMatrix4fvARB)
+GLAPI_ENTRY(UseProgramObjectARB)
+GLAPI_ENTRY(ValidateProgramARB)
+GLAPI_ENTRY(BindAttribLocationARB)
+GLAPI_ENTRY(GetActiveAttribARB)
+GLAPI_ENTRY(GetAttribLocationARB)
+//GLAPI_ENTRY(DrawBuffersARB)
+//GLAPI_ENTRY(PolygonOffsetEXT)
+//GLAPI_ENTRY(GetPixelTexGenParameterfvSGIS)
+//GLAPI_ENTRY(GetPixelTexGenParameterivSGIS)
+//GLAPI_ENTRY(PixelTexGenParameterfSGIS)
+//GLAPI_ENTRY(PixelTexGenParameterfvSGIS)
+//GLAPI_ENTRY(PixelTexGenParameteriSGIS)
+//GLAPI_ENTRY(PixelTexGenParameterivSGIS)
+GLAPI_ENTRY(PointParameterfEXT)
+GLAPI_ENTRY(PointParameterfvEXT)
+GLAPI_ENTRY(LockArraysEXT)
+GLAPI_ENTRY(UnlockArraysEXT)
+//GLAPI_ENTRY(CullParameterdvEXT)
+//GLAPI_ENTRY(CullParameterfvEXT)
+GLAPI_ENTRY(SecondaryColor3bEXT)
+GLAPI_ENTRY(SecondaryColor3bvEXT)
+GLAPI_ENTRY(SecondaryColor3dEXT)
+GLAPI_ENTRY(SecondaryColor3dvEXT)
+GLAPI_ENTRY(SecondaryColor3fEXT)
+GLAPI_ENTRY(SecondaryColor3fvEXT)
+GLAPI_ENTRY(SecondaryColor3iEXT)
+GLAPI_ENTRY(SecondaryColor3ivEXT)
+GLAPI_ENTRY(SecondaryColor3sEXT)
+GLAPI_ENTRY(SecondaryColor3svEXT)
+GLAPI_ENTRY(SecondaryColor3ubEXT)
+GLAPI_ENTRY(SecondaryColor3ubvEXT)
+GLAPI_ENTRY(SecondaryColor3uiEXT)
+GLAPI_ENTRY(SecondaryColor3uivEXT)
+GLAPI_ENTRY(SecondaryColor3usEXT)
+GLAPI_ENTRY(SecondaryColor3usvEXT)
+GLAPI_ENTRY(SecondaryColorPointerEXT)
+GLAPI_ENTRY(MultiDrawArraysEXT)
+GLAPI_ENTRY(MultiDrawElementsEXT)
+GLAPI_ENTRY(FogCoordPointerEXT)
+GLAPI_ENTRY(FogCoorddEXT)
+GLAPI_ENTRY(FogCoorddvEXT)
+GLAPI_ENTRY(FogCoordfEXT)
+GLAPI_ENTRY(FogCoordfvEXT)
+//GLAPI_ENTRY(PixelTexGenSGIX)
+GLAPI_ENTRY(BlendFuncSeparateEXT)
+GLAPI_ENTRY(FlushVertexArrayRangeNV)
+GLAPI_ENTRY(VertexArrayRangeNV)
+GLAPI_ENTRY(CombinerInputNV)
+GLAPI_ENTRY(CombinerOutputNV)
+GLAPI_ENTRY(CombinerParameterfNV)
+GLAPI_ENTRY(CombinerParameterfvNV)
+GLAPI_ENTRY(CombinerParameteriNV)
+GLAPI_ENTRY(CombinerParameterivNV)
+GLAPI_ENTRY(FinalCombinerInputNV)
+GLAPI_ENTRY(GetCombinerInputParameterfvNV)
+GLAPI_ENTRY(GetCombinerInputParameterivNV)
+GLAPI_ENTRY(GetCombinerOutputParameterfvNV)
+GLAPI_ENTRY(GetCombinerOutputParameterivNV)
+GLAPI_ENTRY(GetFinalCombinerInputParameterfvNV)
+GLAPI_ENTRY(GetFinalCombinerInputParameterivNV)
+GLAPI_ENTRY(DeleteFencesNV)
+GLAPI_ENTRY(FinishFenceNV)
+GLAPI_ENTRY(GenFencesNV)
+GLAPI_ENTRY(GetFenceivNV)
+GLAPI_ENTRY(IsFenceNV)
+GLAPI_ENTRY(SetFenceNV)
+GLAPI_ENTRY(TestFenceNV)
+GLAPI_ENTRY(AreProgramsResidentNV)
+GLAPI_ENTRY(BindProgramNV)
+GLAPI_ENTRY(DeleteProgramsNV)
+GLAPI_ENTRY(ExecuteProgramNV)
+GLAPI_ENTRY(GenProgramsNV)
+GLAPI_ENTRY(GetProgramParameterdvNV)
+GLAPI_ENTRY(GetProgramParameterfvNV)
+GLAPI_ENTRY(GetProgramStringNV)
+GLAPI_ENTRY(GetProgramivNV)
+GLAPI_ENTRY(GetTrackMatrixivNV)
+GLAPI_ENTRY(GetVertexAttribPointervNV)
+GLAPI_ENTRY(GetVertexAttribdvNV)
+GLAPI_ENTRY(GetVertexAttribfvNV)
+GLAPI_ENTRY(GetVertexAttribivNV)
+GLAPI_ENTRY(IsProgramNV)
+GLAPI_ENTRY(LoadProgramNV)
+GLAPI_ENTRY(ProgramParameters4dvNV)
+GLAPI_ENTRY(ProgramParameters4fvNV)
+GLAPI_ENTRY(RequestResidentProgramsNV)
+GLAPI_ENTRY(TrackMatrixNV)
+GLAPI_ENTRY(VertexAttrib1dNV)
+GLAPI_ENTRY(VertexAttrib1dvNV)
+GLAPI_ENTRY(VertexAttrib1fNV)
+GLAPI_ENTRY(VertexAttrib1fvNV)
+GLAPI_ENTRY(VertexAttrib1sNV)
+GLAPI_ENTRY(VertexAttrib1svNV)
+GLAPI_ENTRY(VertexAttrib2dNV)
+GLAPI_ENTRY(VertexAttrib2dvNV)
+GLAPI_ENTRY(VertexAttrib2fNV)
+GLAPI_ENTRY(VertexAttrib2fvNV)
+GLAPI_ENTRY(VertexAttrib2sNV)
+GLAPI_ENTRY(VertexAttrib2svNV)
+GLAPI_ENTRY(VertexAttrib3dNV)
+GLAPI_ENTRY(VertexAttrib3dvNV)
+GLAPI_ENTRY(VertexAttrib3fNV)
+GLAPI_ENTRY(VertexAttrib3fvNV)
+GLAPI_ENTRY(VertexAttrib3sNV)
+GLAPI_ENTRY(VertexAttrib3svNV)
+GLAPI_ENTRY(VertexAttrib4dNV)
+GLAPI_ENTRY(VertexAttrib4dvNV)
+GLAPI_ENTRY(VertexAttrib4fNV)
+GLAPI_ENTRY(VertexAttrib4fvNV)
+GLAPI_ENTRY(VertexAttrib4sNV)
+GLAPI_ENTRY(VertexAttrib4svNV)
+GLAPI_ENTRY(VertexAttrib4ubNV)
+GLAPI_ENTRY(VertexAttrib4ubvNV)
+GLAPI_ENTRY(VertexAttribPointerNV)
+GLAPI_ENTRY(VertexAttribs1dvNV)
+GLAPI_ENTRY(VertexAttribs1fvNV)
+GLAPI_ENTRY(VertexAttribs1svNV)
+GLAPI_ENTRY(VertexAttribs2dvNV)
+GLAPI_ENTRY(VertexAttribs2fvNV)
+GLAPI_ENTRY(VertexAttribs2svNV)
+GLAPI_ENTRY(VertexAttribs3dvNV)
+GLAPI_ENTRY(VertexAttribs3fvNV)
+GLAPI_ENTRY(VertexAttribs3svNV)
+GLAPI_ENTRY(VertexAttribs4dvNV)
+GLAPI_ENTRY(VertexAttribs4fvNV)
+GLAPI_ENTRY(VertexAttribs4svNV)
+GLAPI_ENTRY(VertexAttribs4ubvNV)
+GLAPI_ENTRY(PointParameteriNV)
+GLAPI_ENTRY(PointParameterivNV)
+GLAPI_ENTRY(GetProgramNamedParameterdvNV)
+GLAPI_ENTRY(GetProgramNamedParameterfvNV)
+GLAPI_ENTRY(ProgramNamedParameter4dNV)
+GLAPI_ENTRY(ProgramNamedParameter4dvNV)
+GLAPI_ENTRY(ProgramNamedParameter4fNV)
+GLAPI_ENTRY(ProgramNamedParameter4fvNV)
+//GLAPI_ENTRY(BlendEquationSeparateEXT)
+GLAPI_ENTRY(BindFramebufferEXT)
+GLAPI_ENTRY(BindRenderbufferEXT)
+GLAPI_ENTRY(CheckFramebufferStatusEXT)
+GLAPI_ENTRY(DeleteFramebuffersEXT)
+GLAPI_ENTRY(DeleteRenderbuffersEXT)
+GLAPI_ENTRY(FramebufferRenderbufferEXT)
+GLAPI_ENTRY(FramebufferTexture1DEXT)
+GLAPI_ENTRY(FramebufferTexture2DEXT)
+GLAPI_ENTRY(FramebufferTexture3DEXT)
+GLAPI_ENTRY(GenFramebuffersEXT)
+GLAPI_ENTRY(GenRenderbuffersEXT)
+GLAPI_ENTRY(GenerateMipmapEXT)
+GLAPI_ENTRY(GetFramebufferAttachmentParameterivEXT)
+GLAPI_ENTRY(GetRenderbufferParameterivEXT)
+GLAPI_ENTRY(IsFramebufferEXT)
+GLAPI_ENTRY(IsRenderbufferEXT)
+GLAPI_ENTRY(RenderbufferStorageEXT)
+
diff --git a/src/VBox/Additions/common/crOpenGL/fakedri_glxfuncsList.h b/src/VBox/Additions/common/crOpenGL/fakedri_glxfuncsList.h
new file mode 100644
index 00000000..c1e7274d
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/fakedri_glxfuncsList.h
@@ -0,0 +1,93 @@
+/* $Id: fakedri_glxfuncsList.h $ */
+/** @file
+ * VBox OpenGL list of opengl functions common in Mesa and vbox opengl stub
+ */
+
+/*
+ * Copyright (C) 2009-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef GLXAPI_ENTRY
+#error GLXAPI_ENTRY should be defined.
+#endif
+
+/*This should match glX* entries which are exported by Mesa's libGL.so,
+ * use something like the following to get the list:
+ * objdump -T libGL.so|grep glX|grep -v __|awk '{print $7;};'|sed 's/glX//'|awk '{OFS=""; print "GLXAPI_ENTRY(",$1,")"}'
+ */
+
+/* #######Note: if you change the list, don't forget to change Linux_i386_glxapi_exports.py####### */
+
+GLXAPI_ENTRY(CopyContext)
+GLXAPI_ENTRY(UseXFont)
+/*GLXAPI_ENTRY(GetDriverConfig)*/
+GLXAPI_ENTRY(GetProcAddress)
+GLXAPI_ENTRY(QueryExtension)
+GLXAPI_ENTRY(IsDirect)
+GLXAPI_ENTRY(DestroyGLXPbufferSGIX)
+GLXAPI_ENTRY(QueryGLXPbufferSGIX)
+GLXAPI_ENTRY(CreateGLXPixmap)
+GLXAPI_ENTRY(CreateGLXPixmapWithConfigSGIX)
+GLXAPI_ENTRY(QueryContext)
+GLXAPI_ENTRY(CreateContextWithConfigSGIX)
+GLXAPI_ENTRY(SwapBuffers)
+GLXAPI_ENTRY(CreateNewContext)
+GLXAPI_ENTRY(SelectEventSGIX)
+GLXAPI_ENTRY(GetCurrentDrawable)
+GLXAPI_ENTRY(ChooseFBConfig)
+GLXAPI_ENTRY(WaitGL)
+GLXAPI_ENTRY(GetFBConfigs)
+GLXAPI_ENTRY(CreatePixmap)
+GLXAPI_ENTRY(GetSelectedEventSGIX)
+GLXAPI_ENTRY(GetCurrentReadDrawable)
+GLXAPI_ENTRY(GetCurrentDisplay)
+GLXAPI_ENTRY(QueryServerString)
+GLXAPI_ENTRY(CreateWindow)
+GLXAPI_ENTRY(SelectEvent)
+GLXAPI_ENTRY(GetVisualFromFBConfigSGIX)
+GLXAPI_ENTRY(GetFBConfigFromVisualSGIX)
+GLXAPI_ENTRY(QueryDrawable)
+GLXAPI_ENTRY(CreateContext)
+GLXAPI_ENTRY(GetConfig)
+GLXAPI_ENTRY(CreateGLXPbufferSGIX)
+GLXAPI_ENTRY(CreatePbuffer)
+GLXAPI_ENTRY(ChooseFBConfigSGIX)
+GLXAPI_ENTRY(WaitX)
+GLXAPI_ENTRY(GetVisualFromFBConfig)
+/*GLXAPI_ENTRY(GetScreenDriver)*/
+GLXAPI_ENTRY(GetFBConfigAttrib)
+GLXAPI_ENTRY(GetCurrentContext)
+GLXAPI_ENTRY(GetClientString)
+GLXAPI_ENTRY(DestroyPixmap)
+GLXAPI_ENTRY(MakeCurrent)
+GLXAPI_ENTRY(DestroyContext)
+GLXAPI_ENTRY(GetProcAddressARB)
+GLXAPI_ENTRY(GetSelectedEvent)
+GLXAPI_ENTRY(DestroyPbuffer)
+GLXAPI_ENTRY(DestroyWindow)
+GLXAPI_ENTRY(DestroyGLXPixmap)
+GLXAPI_ENTRY(QueryVersion)
+GLXAPI_ENTRY(ChooseVisual)
+GLXAPI_ENTRY(MakeContextCurrent)
+GLXAPI_ENTRY(QueryExtensionsString)
+GLXAPI_ENTRY(GetFBConfigAttribSGIX)
+#ifdef VBOXOGL_FAKEDRI
+GLXAPI_ENTRY(FreeMemoryMESA)
+GLXAPI_ENTRY(QueryContextInfoEXT)
+GLXAPI_ENTRY(ImportContextEXT)
+GLXAPI_ENTRY(GetContextIDEXT)
+GLXAPI_ENTRY(MakeCurrentReadSGI)
+GLXAPI_ENTRY(AllocateMemoryMESA)
+GLXAPI_ENTRY(GetMemoryOffsetMESA)
+GLXAPI_ENTRY(CreateGLXPixmapMESA)
+GLXAPI_ENTRY(GetCurrentDisplayEXT)
+GLXAPI_ENTRY(FreeContextEXT)
+#endif
diff --git a/src/VBox/Additions/common/crOpenGL/feedback/Makefile.kup b/src/VBox/Additions/common/crOpenGL/feedback/Makefile.kup
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/feedback/Makefile.kup
diff --git a/src/VBox/Additions/common/crOpenGL/feedback/feedback.def b/src/VBox/Additions/common/crOpenGL/feedback/feedback.def
new file mode 100644
index 00000000..9edc7163
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/feedback/feedback.def
@@ -0,0 +1,6 @@
+; Copyright (c) 2001, Stanford University
+; All rights reserved.
+;
+; See the file LICENSE.txt for information on redistributing this software.
+EXPORTS
+SPULoad
diff --git a/src/VBox/Additions/common/crOpenGL/feedback/feedback.py b/src/VBox/Additions/common/crOpenGL/feedback/feedback.py
new file mode 100755
index 00000000..181b23fd
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/feedback/feedback.py
@@ -0,0 +1,270 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+
+apiutil.CopyrightC()
+
+print("""
+/* DO NOT EDIT - generated by feedback.py */
+#include <stdio.h>
+#include "cr_spu.h"
+#include "feedbackspu.h"
+#include "feedbackspu_proto.h"
+#include "cr_packfunctions.h"
+#include "cr_glstate.h"
+
+""")
+
+keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+for func_name in keys:
+ return_type = apiutil.ReturnType(func_name)
+ params = apiutil.Parameters(func_name)
+ if apiutil.FindSpecial( "feedback", func_name ):
+ print('static %s FEEDBACKSPU_APIENTRY feedbackspu_%s(%s)' % ( return_type, func_name, apiutil.MakeDeclarationString(params) ))
+ print('{')
+ print('\tfeedback_spu.super.%s(%s);' % ( func_name, apiutil.MakeCallString(params) ))
+ print('}')
+
+
+
+print("""
+#define CHANGE(name, func) crSPUChangeInterface((void *)&(feedback_spu.self), (void *)feedback_spu.self.name, (void *)((SPUGenericFunction) func))
+#define CHANGESWAP(name, swapfunc, regfunc) crSPUChangeInterface( (void *)&(feedback_spu.self), (void *)feedback_spu.self.name, (void *)((SPUGenericFunction) (feedback_spu.swap ? swapfunc: regfunc )))
+
+static void __loadFeedbackAPI( void )
+{
+""")
+for func_name in keys:
+ return_type = apiutil.ReturnType(func_name)
+ params = apiutil.Parameters(func_name)
+ if apiutil.FindSpecial( "feedback", func_name ):
+ print('\tCHANGE(%s, crStateFeedback%s);' % (func_name, func_name ))
+print("""
+}
+
+static void __loadSelectAPI( void )
+{
+""")
+for func_name in keys:
+ if apiutil.FindSpecial( "select", func_name ):
+ print('\tCHANGE(%s, crStateSelect%s);' % (func_name, func_name ))
+ elif apiutil.FindSpecial( "feedback", func_name ):
+ print('\tCHANGE(%s, feedbackspu_%s);' % (func_name, func_name ))
+print("""
+}
+
+static void __loadRenderAPI( void )
+{
+""")
+
+for func_name in keys:
+ return_type = apiutil.ReturnType(func_name)
+ if apiutil.FindSpecial( "feedback", func_name ) or apiutil.FindSpecial( "select", func_name ):
+ print('\tCHANGE(%s, feedbackspu_%s);' % (func_name, func_name ))
+print("""
+}
+""")
+
+print("""
+static GLint FEEDBACKSPU_APIENTRY feedbackspu_RenderMode ( GLenum mode )
+{
+ feedback_spu.render_mode = mode;
+
+ switch (mode) {
+ case GL_FEEDBACK:
+ /*printf("Switching to Feedback API\\n");*/
+ __loadFeedbackAPI( );
+ break;
+ case GL_SELECT:
+ /*printf("Switching to Selection API\\n");*/
+ __loadSelectAPI( );
+ break;
+ case GL_RENDER:
+ /*printf("Switching to Render API\\n");*/
+ __loadRenderAPI( );
+ break;
+ }
+
+ return crStateRenderMode( mode );
+}
+
+static void FEEDBACKSPU_APIENTRY feedbackspu_Begin ( GLenum mode )
+{
+ if (feedback_spu.render_mode == GL_FEEDBACK)
+ crStateFeedbackBegin( mode );
+ else if (feedback_spu.render_mode == GL_SELECT)
+ crStateSelectBegin( mode );
+ else
+ {
+ crStateBegin( mode );
+ feedback_spu.super.Begin( mode );
+ }
+}
+
+static void FEEDBACKSPU_APIENTRY feedbackspu_End ( void )
+{
+ if (feedback_spu.render_mode == GL_FEEDBACK)
+ crStateFeedbackEnd( );
+ else if (feedback_spu.render_mode == GL_SELECT)
+ crStateSelectEnd( );
+ else
+ {
+ crStateEnd( );
+ feedback_spu.super.End( );
+ }
+}
+
+static void FEEDBACKSPU_APIENTRY feedbackspu_Bitmap ( GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap )
+{
+ crStateBitmap( width, height, xorig, yorig, xmove, ymove, bitmap );
+
+ if (feedback_spu.render_mode == GL_FEEDBACK)
+ crStateFeedbackBitmap( width, height, xorig, yorig, xmove, ymove, bitmap );
+ else if (feedback_spu.render_mode == GL_SELECT)
+ crStateSelectBitmap( width, height, xorig, yorig, xmove, ymove, bitmap );
+ else
+ feedback_spu.super.Bitmap( width, height, xorig, yorig, xmove, ymove, bitmap );
+}
+
+static void FEEDBACKSPU_APIENTRY feedbackspu_CopyPixels( GLint x, GLint y, GLsizei width, GLsizei height, GLenum type )
+{
+ if (feedback_spu.render_mode == GL_FEEDBACK)
+ crStateFeedbackCopyPixels( x, y, width, height, type );
+ else if (feedback_spu.render_mode == GL_SELECT)
+ crStateSelectCopyPixels( x, y, width, height, type );
+ else
+ feedback_spu.super.CopyPixels( x, y, width, height, type );
+}
+
+static void FEEDBACKSPU_APIENTRY feedbackspu_DrawPixels( GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels )
+{
+ if (feedback_spu.render_mode == GL_FEEDBACK)
+ crStateFeedbackDrawPixels( width, height, format, type, pixels );
+ else if (feedback_spu.render_mode == GL_SELECT)
+ crStateSelectDrawPixels( width, height, format, type, pixels );
+ else
+ feedback_spu.super.DrawPixels( width, height, format, type, pixels );
+}
+
+static void FEEDBACKSPU_APIENTRY feedbackspu_GetBooleanv( GLenum pname, GLboolean *params )
+
+{
+ if (pname == GL_FEEDBACK_BUFFER_SIZE ||
+ pname == GL_FEEDBACK_BUFFER_TYPE ||
+ pname == GL_SELECTION_BUFFER_SIZE)
+ crStateFeedbackGetBooleanv( pname, params );
+ else
+ if (pname == GL_VIEWPORT && feedback_spu.default_viewport)
+ crStateGetBooleanv( pname, params );
+ else
+ feedback_spu.super.GetBooleanv( pname, params );
+}
+
+static void FEEDBACKSPU_APIENTRY feedbackspu_GetDoublev( GLenum pname, GLdouble *params )
+
+{
+ if (pname == GL_FEEDBACK_BUFFER_SIZE ||
+ pname == GL_FEEDBACK_BUFFER_TYPE ||
+ pname == GL_SELECTION_BUFFER_SIZE)
+ crStateFeedbackGetDoublev( pname, params );
+ else
+ if (pname == GL_VIEWPORT && feedback_spu.default_viewport)
+ crStateGetDoublev( pname, params );
+ else
+ feedback_spu.super.GetDoublev( pname, params );
+}
+
+static void FEEDBACKSPU_APIENTRY feedbackspu_GetFloatv( GLenum pname, GLfloat *params )
+
+{
+ if (pname == GL_FEEDBACK_BUFFER_SIZE ||
+ pname == GL_FEEDBACK_BUFFER_TYPE ||
+ pname == GL_SELECTION_BUFFER_SIZE)
+ crStateFeedbackGetFloatv( pname, params );
+ else
+ if (pname == GL_VIEWPORT && feedback_spu.default_viewport)
+ crStateGetFloatv( pname, params );
+ else
+ feedback_spu.super.GetFloatv( pname, params );
+}
+
+static void FEEDBACKSPU_APIENTRY feedbackspu_GetIntegerv( GLenum pname, GLint *params )
+
+{
+ if (pname == GL_FEEDBACK_BUFFER_SIZE ||
+ pname == GL_FEEDBACK_BUFFER_TYPE ||
+ pname == GL_SELECTION_BUFFER_SIZE)
+ crStateFeedbackGetIntegerv( pname, params );
+ else
+ if (pname == GL_VIEWPORT && feedback_spu.default_viewport)
+ crStateGetIntegerv( pname, params );
+ else
+ feedback_spu.super.GetIntegerv( pname, params );
+}
+
+SPUNamedFunctionTable _cr_feedback_table[] = {
+""")
+
+for func_name in keys:
+ if apiutil.FindSpecial( "feedback_state", func_name ):
+ print('\t{ "%s", (SPUGenericFunction) feedbackspu_%s }, ' % ( func_name, func_name ))
+print("""
+ { "GetBooleanv", (SPUGenericFunction) feedbackspu_GetBooleanv },
+ { "GetDoublev", (SPUGenericFunction) feedbackspu_GetDoublev },
+ { "GetFloatv", (SPUGenericFunction) feedbackspu_GetFloatv },
+ { "GetIntegerv", (SPUGenericFunction) feedbackspu_GetIntegerv },
+ { "FeedbackBuffer", (SPUGenericFunction) crStateFeedbackBuffer },
+ { "SelectBuffer", (SPUGenericFunction) crStateSelectBuffer },
+ { "InitNames", (SPUGenericFunction) crStateInitNames },
+ { "LoadName", (SPUGenericFunction) crStateLoadName },
+ { "PushName", (SPUGenericFunction) crStatePushName },
+ { "PopName", (SPUGenericFunction) crStatePopName },
+ { "Begin", (SPUGenericFunction) feedbackspu_Begin },
+ { "End", (SPUGenericFunction) feedbackspu_End },
+ { "Bitmap", (SPUGenericFunction) feedbackspu_Bitmap },
+ { "CopyPixels", (SPUGenericFunction) feedbackspu_CopyPixels },
+ { "DrawPixels", (SPUGenericFunction) feedbackspu_DrawPixels },
+ { "TexCoord1d", (SPUGenericFunction) feedbackspu_TexCoord1d },
+ { "TexCoord1dv", (SPUGenericFunction) feedbackspu_TexCoord1dv },
+ { "TexCoord1f", (SPUGenericFunction) feedbackspu_TexCoord1f },
+ { "TexCoord1fv", (SPUGenericFunction) feedbackspu_TexCoord1fv },
+ { "TexCoord1s", (SPUGenericFunction) feedbackspu_TexCoord1s },
+ { "TexCoord1sv", (SPUGenericFunction) feedbackspu_TexCoord1sv },
+ { "TexCoord1i", (SPUGenericFunction) feedbackspu_TexCoord1i },
+ { "TexCoord1iv", (SPUGenericFunction) feedbackspu_TexCoord1iv },
+ { "TexCoord2d", (SPUGenericFunction) feedbackspu_TexCoord2d },
+ { "TexCoord2dv", (SPUGenericFunction) feedbackspu_TexCoord2dv },
+ { "TexCoord2f", (SPUGenericFunction) feedbackspu_TexCoord2f },
+ { "TexCoord2fv", (SPUGenericFunction) feedbackspu_TexCoord2fv },
+ { "TexCoord2s", (SPUGenericFunction) feedbackspu_TexCoord2s },
+ { "TexCoord2sv", (SPUGenericFunction) feedbackspu_TexCoord2sv },
+ { "TexCoord2i", (SPUGenericFunction) feedbackspu_TexCoord2i },
+ { "TexCoord2iv", (SPUGenericFunction) feedbackspu_TexCoord2iv },
+ { "TexCoord3d", (SPUGenericFunction) feedbackspu_TexCoord3d },
+ { "TexCoord3dv", (SPUGenericFunction) feedbackspu_TexCoord3dv },
+ { "TexCoord3f", (SPUGenericFunction) feedbackspu_TexCoord3f },
+ { "TexCoord3fv", (SPUGenericFunction) feedbackspu_TexCoord3fv },
+ { "TexCoord3s", (SPUGenericFunction) feedbackspu_TexCoord3s },
+ { "TexCoord3sv", (SPUGenericFunction) feedbackspu_TexCoord3sv },
+ { "TexCoord3i", (SPUGenericFunction) feedbackspu_TexCoord3i },
+ { "TexCoord3iv", (SPUGenericFunction) feedbackspu_TexCoord3iv },
+ { "TexCoord4d", (SPUGenericFunction) feedbackspu_TexCoord4d },
+ { "TexCoord4dv", (SPUGenericFunction) feedbackspu_TexCoord4dv },
+ { "TexCoord4f", (SPUGenericFunction) feedbackspu_TexCoord4f },
+ { "TexCoord4fv", (SPUGenericFunction) feedbackspu_TexCoord4fv },
+ { "TexCoord4s", (SPUGenericFunction) feedbackspu_TexCoord4s },
+ { "TexCoord4sv", (SPUGenericFunction) feedbackspu_TexCoord4sv },
+ { "TexCoord4i", (SPUGenericFunction) feedbackspu_TexCoord4i },
+ { "TexCoord4iv", (SPUGenericFunction) feedbackspu_TexCoord4iv },
+ { "RenderMode", (SPUGenericFunction) feedbackspu_RenderMode },
+ { NULL, NULL }
+};
+""")
diff --git a/src/VBox/Additions/common/crOpenGL/feedback/feedback_context.c b/src/VBox/Additions/common/crOpenGL/feedback/feedback_context.c
new file mode 100644
index 00000000..11158b5a
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/feedback/feedback_context.c
@@ -0,0 +1,131 @@
+/* $Id: feedback_context.c $ */
+/** @file
+ * VBox feedback spu, context tracking.
+ */
+
+/*
+ * Copyright (C) 2009-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include "cr_spu.h"
+#include "cr_error.h"
+#include "feedbackspu.h"
+
+/** @todo r=bird: None of the code here is referenced externally, so I've
+ * just prototyped the function here at the top of the file to make
+ * the compiler happy. */
+GLint FEEDBACKSPU_APIENTRY feedbackspu_VBoxCreateContext( GLint con, const char *dpyName, GLint visual, GLint shareCtx );
+GLint FEEDBACKSPU_APIENTRY feedbackspu_CreateContext( const char *dpyName, GLint visual, GLint shareCtx );
+void FEEDBACKSPU_APIENTRY feedbackspu_MakeCurrent( GLint window, GLint nativeWindow, GLint ctx );
+void FEEDBACKSPU_APIENTRY feedbackspu_DestroyContext( GLint ctx );
+
+
+/** @todo Multithreading case. (See feedback_spu.self.RenderMode)*/
+
+GLint FEEDBACKSPU_APIENTRY
+feedbackspu_VBoxCreateContext( GLint con, const char *dpyName, GLint visual, GLint shareCtx )
+{
+ GLint ctx, slot;
+
+#ifdef CHROMIUM_THREADSAFE
+ crLockMutex(&feedback_spu.mutex);
+#endif
+
+ ctx = feedback_spu.child.VBoxCreateContext(con, dpyName, visual, shareCtx);
+
+ /* find an empty context slot */
+ for (slot = 0; slot < feedback_spu.numContexts; slot++) {
+ if (!feedback_spu.context[slot].clientState) {
+ /* found empty slot */
+ break;
+ }
+ }
+ if (slot == feedback_spu.numContexts) {
+ feedback_spu.numContexts++;
+ }
+
+ feedback_spu.context[slot].clientState = crStateCreateContext(NULL, visual, NULL);
+ feedback_spu.context[slot].clientCtx = ctx;
+
+#ifdef CHROMIUM_THREADSAFE
+ crUnlockMutex(&feedback_spu.mutex);
+#endif
+
+ return ctx;
+}
+
+GLint FEEDBACKSPU_APIENTRY
+feedbackspu_CreateContext( const char *dpyName, GLint visual, GLint shareCtx )
+{
+ return feedbackspu_VBoxCreateContext( 0, dpyName, visual, shareCtx );
+}
+
+void FEEDBACKSPU_APIENTRY
+feedbackspu_MakeCurrent( GLint window, GLint nativeWindow, GLint ctx )
+{
+#ifdef CHROMIUM_THREADSAFE
+ crLockMutex(&feedback_spu.mutex);
+#endif
+ feedback_spu.child.MakeCurrent(window, nativeWindow, ctx);
+
+ if (ctx) {
+ int slot;
+ GLint oldmode;
+
+ for (slot=0; slot<feedback_spu.numContexts; ++slot)
+ if (feedback_spu.context[slot].clientCtx == ctx) break;
+ CRASSERT(slot < feedback_spu.numContexts);
+
+ crStateMakeCurrent(feedback_spu.context[slot].clientState);
+
+ crStateGetIntegerv(GL_RENDER_MODE, &oldmode);
+
+ if (oldmode!=feedback_spu.render_mode)
+ {
+ feedback_spu.self.RenderMode(oldmode);
+ }
+ }
+ else
+ {
+ crStateMakeCurrent(NULL);
+ }
+
+#ifdef CHROMIUM_THREADSAFE
+ crUnlockMutex(&feedback_spu.mutex);
+#endif
+}
+
+void FEEDBACKSPU_APIENTRY
+feedbackspu_DestroyContext( GLint ctx )
+{
+#ifdef CHROMIUM_THREADSAFE
+ crLockMutex(&feedback_spu.mutex);
+#endif
+ feedback_spu.child.DestroyContext(ctx);
+
+ if (ctx) {
+ int slot;
+
+ for (slot=0; slot<feedback_spu.numContexts; ++slot)
+ if (feedback_spu.context[slot].clientCtx == ctx) break;
+ CRASSERT(slot < feedback_spu.numContexts);
+
+ crStateDestroyContext(feedback_spu.context[slot].clientState);
+
+ feedback_spu.context[slot].clientState = NULL;
+ feedback_spu.context[slot].clientCtx = 0;
+ }
+
+#ifdef CHROMIUM_THREADSAFE
+ crUnlockMutex(&feedback_spu.mutex);
+#endif
+}
+
diff --git a/src/VBox/Additions/common/crOpenGL/feedback/feedback_funcs.py b/src/VBox/Additions/common/crOpenGL/feedback/feedback_funcs.py
new file mode 100755
index 00000000..d3c40833
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/feedback/feedback_funcs.py
@@ -0,0 +1,40 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+
+apiutil.CopyrightC()
+
+print("""
+/* DO NOT EDIT - THIS FILE AUTOMATICALLY GENERATED BY feedback_funcs.py SCRIPT */
+#ifndef CR_STATE_FEEDBACK_FUNCS_H
+#define CR_STATE_FEEDBACK_FUNCS_H
+
+#include "cr_error.h"
+
+#if defined(WINDOWS)
+#define STATE_APIENTRY __stdcall
+#else
+#define STATE_APIENTRY
+#endif
+
+#define STATE_UNUSED(x) ((void)x)""")
+
+keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+for func_name in apiutil.AllSpecials( "feedback" ):
+ return_type = apiutil.ReturnType(func_name)
+ params = apiutil.Parameters(func_name)
+ print('%s STATE_APIENTRY crStateFeedback%s(%s);' % (return_type, func_name, apiutil.MakeDeclarationString(params)))
+
+for func_name in apiutil.AllSpecials( "select" ):
+ return_type = apiutil.ReturnType(func_name)
+ params = apiutil.Parameters(func_name)
+ print('%s STATE_APIENTRY crStateSelect%s(%s);' % (return_type, func_name, apiutil.MakeDeclarationString(params)))
+print('\n#endif /* CR_STATE_FEEDBACK_FUNCS_H */')
diff --git a/src/VBox/Additions/common/crOpenGL/feedback/feedback_special b/src/VBox/Additions/common/crOpenGL/feedback/feedback_special
new file mode 100644
index 00000000..75eb7f8f
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/feedback/feedback_special
@@ -0,0 +1,64 @@
+Vertex2d
+Vertex2dv
+Vertex2f
+Vertex2fv
+Vertex2i
+Vertex2iv
+Vertex2s
+Vertex2sv
+Vertex3d
+Vertex3dv
+Vertex3f
+Vertex3fv
+Vertex3i
+Vertex3iv
+Vertex3s
+Vertex3sv
+Vertex4d
+Vertex4dv
+Vertex4f
+Vertex4fv
+Vertex4i
+Vertex4iv
+Vertex4s
+Vertex4sv
+Rectf
+Recti
+Rectd
+Rects
+Rectiv
+Rectfv
+Rectdv
+Rectsv
+TexCoord1d
+TexCoord1dv
+TexCoord1f
+TexCoord1fv
+TexCoord1i
+TexCoord1iv
+TexCoord1s
+TexCoord1sv
+TexCoord2d
+TexCoord2dv
+TexCoord2f
+TexCoord2fv
+TexCoord2i
+TexCoord2iv
+TexCoord2s
+TexCoord2sv
+TexCoord3d
+TexCoord3dv
+TexCoord3f
+TexCoord3fv
+TexCoord3i
+TexCoord3iv
+TexCoord3s
+TexCoord3sv
+TexCoord4d
+TexCoord4dv
+TexCoord4f
+TexCoord4fv
+TexCoord4i
+TexCoord4iv
+TexCoord4s
+TexCoord4sv
diff --git a/src/VBox/Additions/common/crOpenGL/feedback/feedback_state.py b/src/VBox/Additions/common/crOpenGL/feedback/feedback_state.py
new file mode 100755
index 00000000..01bab425
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/feedback/feedback_state.py
@@ -0,0 +1,34 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+
+apiutil.CopyrightC()
+
+print("""
+#include "cr_server.h"
+#include "feedbackspu.h"
+#include "feedbackspu_proto.h"
+""")
+custom = ["CreateContext", "VBoxCreateContext", "MakeCurrent", "DestroyContext"]
+
+keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+for func_name in keys:
+ if apiutil.FindSpecial( "feedback_state", func_name ):
+ if func_name in custom:
+ continue
+ return_type = apiutil.ReturnType(func_name)
+ params = apiutil.Parameters(func_name)
+ print('%s FEEDBACKSPU_APIENTRY feedbackspu_%s(%s)' % (return_type, func_name, apiutil.MakeDeclarationString(params)))
+ print('{')
+ print('\tcrState%s(%s);' % (func_name, apiutil.MakeCallString(params)))
+ print('')
+ print('\tfeedback_spu.super.%s(%s);' % (func_name, apiutil.MakeCallString(params)))
+ print('}')
diff --git a/src/VBox/Additions/common/crOpenGL/feedback/feedback_state_special b/src/VBox/Additions/common/crOpenGL/feedback/feedback_state_special
new file mode 100644
index 00000000..15bec65d
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/feedback/feedback_state_special
@@ -0,0 +1,66 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+ClipPlane
+MatrixMode
+LoadIdentity
+PopMatrix
+PushMatrix
+LoadMatrixf
+LoadMatrixd
+MultMatrixf
+MultMatrixd
+LoadTransposeMatrixfARB
+LoadTransposeMatrixdARB
+MultTransposeMatrixfARB
+MultTransposeMatrixdARB
+Translatef
+Translated
+Rotatef
+Rotated
+Scalef
+Scaled
+Frustum
+Ortho
+Viewport
+DepthRange
+Scissor
+PushAttrib
+PopAttrib
+PassThrough
+PolygonMode
+Color4f
+Color4fv
+Color3f
+Color3fv
+RasterPos2d
+RasterPos2dv
+RasterPos2f
+RasterPos2fv
+RasterPos2i
+RasterPos2iv
+RasterPos2s
+RasterPos2sv
+RasterPos3d
+RasterPos3dv
+RasterPos3f
+RasterPos3fv
+RasterPos3i
+RasterPos3iv
+RasterPos3s
+RasterPos3sv
+RasterPos4d
+RasterPos4dv
+RasterPos4f
+RasterPos4fv
+RasterPos4i
+RasterPos4iv
+RasterPos4s
+RasterPos4sv
+CreateContext
+MakeCurrent
+DestroyContext
+VBoxAttachThread
+VBoxDetachThread
+VBoxCreateContext
diff --git a/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu.h b/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu.h
new file mode 100644
index 00000000..7d72a70b
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu.h
@@ -0,0 +1,58 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved.
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#ifndef GA_INCLUDED_SRC_common_crOpenGL_feedback_feedbackspu_h
+#define GA_INCLUDED_SRC_common_crOpenGL_feedback_feedbackspu_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#ifdef WINDOWS
+#define FEEDBACKSPU_APIENTRY __stdcall
+#else
+#define FEEDBACKSPU_APIENTRY
+#endif
+
+#include "cr_spu.h"
+#include "cr_timer.h"
+#include "cr_glstate.h"
+
+typedef struct context_info_t ContextInfo;
+
+struct context_info_t {
+ CRContext *clientState; /* used to store client-side GL state */
+ GLint clientCtx; /* client context ID */
+};
+
+typedef struct {
+ int id;
+ int has_child;
+ SPUDispatchTable self, child, super;
+
+ int render_mode;
+
+ int default_viewport;
+
+ CRCurrentStatePointers current;
+
+ CRContext *defaultctx;
+ int numContexts;
+ ContextInfo context[CR_MAX_CONTEXTS];
+
+#ifdef CHROMIUM_THREADSAFE
+ CRmutex mutex;
+#endif
+} feedbackSPU;
+
+extern feedbackSPU feedback_spu;
+
+extern SPUNamedFunctionTable _cr_feedback_table[];
+
+extern SPUOptions feedbackSPUOptions[];
+
+extern void feedbackspuGatherConfiguration( void );
+
+#endif /* !GA_INCLUDED_SRC_common_crOpenGL_feedback_feedbackspu_h */
diff --git a/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu.rc b/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu.rc
new file mode 100644
index 00000000..b9db8122
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu.rc
@@ -0,0 +1,69 @@
+/* $Id: feedbackspu.rc $ */
+/** @file
+ * VBoxOGLfeedbackspu - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2009-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_RC_FILE_VERSION
+ PRODUCTVERSION VBOX_RC_FILE_VERSION
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS VBOX_RC_FILE_FLAGS
+ FILEOS VBOX_RC_FILE_OS
+ FILETYPE VBOX_RC_TYPE_DRV
+ FILESUBTYPE VFT2_DRV_DISPLAY
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "VirtualBox crOpenGL ICD\0"
+ VALUE "InternalName", "VBoxOGLfeedbackpu\0"
+#ifdef VBOX_WDDM_WOW64
+ VALUE "OriginalFilename", "VBoxOGLfeedbackpu-x86.dll\0"
+#else
+ VALUE "OriginalFilename", "VBoxOGLfeedbackpu.dll\0"
+#endif
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileVersion", VBOX_RC_FILE_VERSION_STR
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "ProductName", VBOX_RC_PRODUCT_NAME_GA_STR
+ VALUE "ProductVersion", VBOX_RC_PRODUCT_VERSION_STR
+ VBOX_RC_MORE_STRINGS
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+1 RCDATA
+BEGIN
+// Machine dependent parameters
+ 17, // Height of vertical thumb
+ 17, // Width of horizontal thumb
+ 2, // Icon horiz compression factor
+ 2, // Icon vert compression factor
+ 1, // Cursor horz compression factor
+ 1, // Cursor vert compression factor
+ 0, // Kanji window height
+ 1, // cxBorder (thickness of vertical lines)
+ 1 // cyBorder (thickness of horizontal lines)
+END
diff --git a/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu_config.c b/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu_config.c
new file mode 100644
index 00000000..9449a2bb
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu_config.c
@@ -0,0 +1,44 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "cr_string.h"
+#include "cr_environment.h"
+#include "cr_error.h"
+#include "cr_mem.h"
+#include "feedbackspu.h"
+
+#include <stdio.h>
+#ifndef WINDOWS
+#include <unistd.h>
+#endif
+
+static void __setDefaults( void )
+{
+ feedback_spu.render_mode = GL_RENDER;
+}
+
+static void set_default_viewport( void *foo, const char *response )
+{
+ (void) foo;
+ sscanf( response, "%d", &(feedback_spu.default_viewport) );
+}
+
+/* option, type, nr, default, min, max, title, callback
+ */
+SPUOptions feedbackSPUOptions[] = {
+
+ { "default_viewport", CR_BOOL, 1, "0", "0", "1",
+ "Return default viewport parameters", (SPUOptionCB)set_default_viewport },
+
+ { NULL, CR_BOOL, 0, NULL, NULL, NULL, NULL, NULL },
+
+};
+
+
+void feedbackspuGatherConfiguration( void )
+{
+ __setDefaults();
+}
diff --git a/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu_init.c b/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu_init.c
new file mode 100644
index 00000000..f264763c
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu_init.c
@@ -0,0 +1,86 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "cr_spu.h"
+#include "cr_environment.h"
+#include "cr_string.h"
+#include "cr_error.h"
+#include "cr_mem.h"
+#include "cr_server.h"
+#include "feedbackspu.h"
+#include <fcntl.h>
+#ifndef WINDOWS
+#include <unistd.h>
+#endif
+
+feedbackSPU feedback_spu;
+
+static SPUFunctions feedback_functions = {
+ NULL, /* CHILD COPY */
+ NULL, /* DATA */
+ _cr_feedback_table /* THE ACTUAL FUNCTIONS */
+};
+
+static SPUFunctions *feedbackSPUInit( int id, SPU *child, SPU *self,
+ unsigned int context_id,
+ unsigned int num_contexts )
+{
+ (void) context_id;
+ (void) num_contexts;
+
+#ifdef CHROMIUM_THREADSAFE
+ crInitMutex(&feedback_spu.mutex);
+#endif
+
+ feedback_spu.id = id;
+ feedback_spu.has_child = 0;
+ if (child)
+ {
+ crSPUInitDispatchTable( &(feedback_spu.child) );
+ crSPUCopyDispatchTable( &(feedback_spu.child), &(child->dispatch_table) );
+ feedback_spu.has_child = 1;
+ }
+ crSPUInitDispatchTable( &(feedback_spu.super) );
+ crSPUCopyDispatchTable( &(feedback_spu.super), &(self->superSPU->dispatch_table) );
+ feedbackspuGatherConfiguration();
+
+ /* create/init default state tracker */
+ crStateInit();
+
+ feedback_spu.defaultctx = crStateCreateContext(NULL, 0, NULL);
+ crStateSetCurrent(feedback_spu.defaultctx);
+
+ feedback_spu.numContexts = 0;
+ crMemZero(feedback_spu.context, CR_MAX_CONTEXTS * sizeof(ContextInfo));
+
+ return &feedback_functions;
+}
+
+static void feedbackSPUSelfDispatch(SPUDispatchTable *self)
+{
+ crSPUInitDispatchTable( &(feedback_spu.self) );
+ crSPUCopyDispatchTable( &(feedback_spu.self), self );
+}
+
+static int feedbackSPUCleanup(void)
+{
+ return 1;
+}
+
+int SPULoad( char **name, char **super, SPUInitFuncPtr *init,
+ SPUSelfDispatchFuncPtr *self, SPUCleanupFuncPtr *cleanup,
+ SPUOptionsPtr *options, int *flags )
+{
+ *name = "feedback";
+ *super = "passthrough";
+ *init = feedbackSPUInit;
+ *self = feedbackSPUSelfDispatch;
+ *cleanup = feedbackSPUCleanup;
+ *options = feedbackSPUOptions;
+ *flags = (SPU_NO_PACKER|SPU_NOT_TERMINAL|SPU_MAX_SERVERS_ZERO);
+
+ return 1;
+}
diff --git a/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu_proto.py b/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu_proto.py
new file mode 100755
index 00000000..92a5c1ce
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/feedback/feedbackspu_proto.py
@@ -0,0 +1,35 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+
+apiutil.CopyrightC()
+
+print("""
+/* DO NOT EDIT - generated by feedback.py */
+
+#ifndef FEEDBACKSPU_PROTO_H
+#define FEEDBACKSPU_PROTO_H
+
+#include "feedbackspu.h"
+
+""")
+
+keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+for func_name in keys:
+ if apiutil.FindSpecial( "feedback_state", func_name ):
+ return_type = apiutil.ReturnType(func_name)
+ params = apiutil.Parameters(func_name)
+ print('extern %s FEEDBACKSPU_APIENTRY feedbackspu_%s(%s);' % (return_type, func_name, apiutil.MakeDeclarationString(params)))
+
+
+print("""
+#endif
+""")
diff --git a/src/VBox/Additions/common/crOpenGL/feedback/select_special b/src/VBox/Additions/common/crOpenGL/feedback/select_special
new file mode 100644
index 00000000..f35dba0a
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/feedback/select_special
@@ -0,0 +1,56 @@
+Vertex2d
+Vertex2dv
+Vertex2f
+Vertex2fv
+Vertex2i
+Vertex2iv
+Vertex2s
+Vertex2sv
+Vertex3d
+Vertex3dv
+Vertex3f
+Vertex3fv
+Vertex3i
+Vertex3iv
+Vertex3s
+Vertex3sv
+Vertex4d
+Vertex4dv
+Vertex4f
+Vertex4fv
+Vertex4i
+Vertex4iv
+Vertex4s
+Vertex4sv
+Rectf
+Recti
+Rectd
+Rects
+Rectiv
+Rectfv
+Rectdv
+Rectsv
+RasterPos2d
+RasterPos2dv
+RasterPos2f
+RasterPos2fv
+RasterPos2i
+RasterPos2iv
+RasterPos2s
+RasterPos2sv
+RasterPos3d
+RasterPos3dv
+RasterPos3f
+RasterPos3fv
+RasterPos3i
+RasterPos3iv
+RasterPos3s
+RasterPos3sv
+RasterPos4d
+RasterPos4dv
+RasterPos4f
+RasterPos4fv
+RasterPos4i
+RasterPos4iv
+RasterPos4s
+RasterPos4sv
diff --git a/src/VBox/Additions/common/crOpenGL/getprocaddress.py b/src/VBox/Additions/common/crOpenGL/getprocaddress.py
new file mode 100755
index 00000000..39cfdf94
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/getprocaddress.py
@@ -0,0 +1,125 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+apiutil.CopyrightC()
+
+print("""
+/* DO NOT EDIT - THIS FILE GENERATED BY THE getprocaddress.py SCRIPT */
+
+#include "chromium.h"
+#include "cr_error.h"
+#include "cr_string.h"
+#include "cr_version.h"
+#include "stub.h"
+#include "dri_glx.h"
+#if defined(VBOXOGL_DRI) || defined(VBOXOGL_FAKEDRI)
+#include "cr_gl.h"
+#include "fakedri_drv.h"
+#endif
+
+struct name_address {
+ const char *name;
+ CR_PROC address;
+};
+
+static struct name_address functions[] = {
+""")
+
+
+keys = apiutil.GetAllFunctions(sys.argv[1]+"/APIspec.txt")
+for func_name in keys:
+ if "Chromium" == apiutil.Category(func_name):
+ continue
+ if "VBox" == apiutil.Category(func_name):
+ continue
+ if func_name == "BoundsInfoCR":
+ continue
+ if "GL_chromium" == apiutil.Category(func_name):
+ pass #continue
+
+ wrap = apiutil.GetCategoryWrapper(func_name)
+ name = "gl" + func_name
+ address = "VBOXGLTAG(gl" + func_name + ")"
+ if wrap:
+ print('#ifdef CR_%s' % wrap)
+ print('\t{ "%s", (CR_PROC) %s },' % (name, address))
+ if wrap:
+ print('#endif')
+
+
+print("\t/* Chromium binding/glue functions */")
+
+for func_name in keys:
+ if (func_name == "Writeback" or
+ func_name == "BoundsInfoCR" or
+ func_name == "GetUniformsLocations" or
+ func_name == "GetAttribsLocations"):
+ continue
+ if apiutil.Category(func_name) == "Chromium":
+ print('\t{ "cr%s", (CR_PROC) cr%s },' % (func_name, func_name))
+
+
+print("""
+ { NULL, NULL }
+};
+
+CR_PROC CR_APIENTRY crGetProcAddress( const char *name )
+{
+ int i;
+ stubInit();
+
+ for (i = 0; functions[i].name; i++) {
+ if (crStrcmp(name, functions[i].name) == 0) {
+ return functions[i].address;
+ }
+ }
+
+
+#define GLXAPI_ENTRY(Func) if (!crStrcmp(name, "glX"#Func)) return (CR_PROC) &VBOXGLXENTRYTAG(glX##Func);
+#include "fakedri_glxfuncsList.h"
+#undef GLXAPI_ENTRY
+
+ /*CR_EXT_texture_from_pixmap*/
+ if (!crStrcmp(name, "glXBindTexImageEXT")) return (CR_PROC) VBOXGLXTAG(glXBindTexImageEXT);
+ if (!crStrcmp(name, "glXReleaseTexImageEXT")) return (CR_PROC) VBOXGLXTAG(glXReleaseTexImageEXT);
+
+#if defined(Linux) && defined(CR_EXT_framebuffer_blit)
+ /* Hacky way to make gnome3 happy on ubuntu 11.04, even though glBlitFramebuffer is part of OpenGL 3.0 spec,
+ * it expects to find glBlitFramebuffer and not glBlitFramebufferEXT after checking for EXT_framebuffer_blit support.
+ * Untill 3.0 support, it's better to go this way instead of adding an alias to src/VBox/GuestHost/OpenGL/glapi_parser/apispec.txt.
+ */
+ if (!crStrcmp(name, "glBlitFramebuffer")) return crGetProcAddress("glBlitFramebufferEXT");
+#endif
+
+ if (name) crDebug("Returning NULL for %s", name);
+ return NULL;
+}
+
+""")
+
+
+
+# XXX should crGetProcAddress really handle WGL/GLX functions???
+
+print_foo = """
+/* As these are Windows specific (i.e. wgl), define these now.... */
+#ifdef WINDOWS
+ {
+ wglGetExtensionsStringEXTFunc_t wglGetExtensionsStringEXT = NULL;
+ wglChoosePixelFormatFunc_t wglChoosePixelFormatEXT = NULL;
+ wglGetPixelFormatAttribivEXTFunc_t wglGetPixelFormatAttribivEXT = NULL;
+ wglGetPixelFormatAttribfvEXTFunc_t wglGetPixelFormatAttribfvEXT = NULL;
+ if (!crStrcmp(name, "wglGetExtensionsStringEXT")) return (CR_PROC) wglGetExtensionsStringEXT;
+ if (!crStrcmp(name, "wglChoosePixelFormatEXT")) return (CR_PROC) wglChoosePixelFormatEXT;
+ if (!crStrcmp(name, "wglGetPixelFormatAttribivEXT")) return (CR_PROC) wglGetPixelFormatAttribivEXT;
+ if (!crStrcmp(name, "wglGetPixelFormatAttribfvEXT")) return (CR_PROC) wglGetPixelFormatAttribfvEXT;
+ }
+#endif
+"""
diff --git a/src/VBox/Additions/common/crOpenGL/glx.c b/src/VBox/Additions/common/crOpenGL/glx.c
new file mode 100644
index 00000000..eb102877
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/glx.c
@@ -0,0 +1,2113 @@
+/* $Id: glx.c $ */
+/** @file
+ * VBox OpenGL GLX implementation
+ */
+
+/*
+ * Copyright (C) 2009-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ * --------------------------------------------------------------------
+ * Original copyright notice:
+ *
+ * Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+/* opengl_stub/glx.c */
+#include "chromium.h"
+#include "cr_error.h"
+#include "cr_spu.h"
+#include "cr_mem.h"
+#include "cr_string.h"
+#include "stub.h"
+#include "dri_glx.h"
+#include "GL/internal/glcore.h"
+#include "cr_glstate.h"
+
+#include <X11/Xregion.h>
+
+/* Force full pixmap update if there're more damaged regions than this number*/
+#define CR_MAX_DAMAGE_REGIONS_TRACKED 50
+
+/* Force "bigger" update (full or clip) if it's reducing number of regions updated
+ * but doesn't increase updated area more than given number
+ */
+#define CR_MIN_DAMAGE_PROFIT_SIZE 64*64
+
+/** @todo combine it in some other place*/
+/* Size of pack spu buffer - some delta for commands packing, see pack/packspu_config.c*/
+
+/** Ramshankar: Solaris compiz fix */
+#ifdef RT_OS_SOLARIS
+# define CR_MAX_TRANSFER_SIZE 20*1024*1024
+#else
+# define CR_MAX_TRANSFER_SIZE 4*1024*1024
+#endif
+
+/** For optimizing glXMakeCurrent */
+static Display *currentDisplay = NULL;
+static GLXDrawable currentDrawable = 0;
+static GLXDrawable currentReadDrawable = 0;
+
+static void stubXshmUpdateImageRect(Display *dpy, GLXDrawable draw, GLX_Pixmap_t *pGlxPixmap, XRectangle *pRect);
+static void stubQueryXDamageExtension(Display *dpy, ContextInfo *pContext);
+
+static bool isGLXVisual(Display *dpy, XVisualInfo *vis)
+{
+ return vis->visualid == XVisualIDFromVisual(DefaultVisual(dpy, vis->screen));
+}
+
+static GLXFBConfig fbConfigFromVisual(Display *dpy, XVisualInfo *vis)
+{
+ (void)dpy;
+
+ if (!isGLXVisual(dpy, vis))
+ return 0;
+ return (GLXFBConfig)vis->visualid;
+}
+
+static GLXFBConfig defaultFBConfigForScreen(Display *dpy, int screen)
+{
+ return (GLXFBConfig) XVisualIDFromVisual(DefaultVisual(dpy, screen));
+}
+
+static XVisualInfo *visualInfoFromFBConfig(Display *dpy, GLXFBConfig config)
+{
+ XVisualInfo info, *pret;
+ int nret;
+
+ info.visualid = (VisualID)config;
+ pret = XGetVisualInfo(dpy, VisualIDMask, &info, &nret);
+ if (nret == 1)
+ return pret;
+ XFree(pret);
+ return NULL;
+}
+
+DECLEXPORT(XVisualInfo *)
+VBOXGLXTAG(glXChooseVisual)( Display *dpy, int screen, int *attribList )
+{
+ bool useRGBA = false;
+ int *attrib;
+ XVisualInfo searchvis, *pret;
+ int nvisuals;
+ stubInit();
+
+ for (attrib = attribList; *attrib != None; attrib++)
+ {
+ switch (*attrib)
+ {
+ case GLX_USE_GL:
+ /* ignored, this is mandatory */
+ break;
+
+ case GLX_BUFFER_SIZE:
+ /* this is for color-index visuals, which we don't support */
+ attrib++;
+ break;
+
+ case GLX_LEVEL:
+ if (attrib[1] != 0)
+ goto err_exit;
+ attrib++;
+ break;
+
+ case GLX_RGBA:
+ useRGBA = true;
+ break;
+
+ case GLX_STEREO:
+ goto err_exit;
+ /*
+ crWarning( "glXChooseVisual: stereo unsupported" );
+ return NULL;
+ */
+ break;
+
+ case GLX_AUX_BUFFERS:
+ if (attrib[1] != 0)
+ goto err_exit;
+ attrib++;
+ break;
+
+ case GLX_RED_SIZE:
+ case GLX_GREEN_SIZE:
+ case GLX_BLUE_SIZE:
+ if (attrib[1] > 8)
+ goto err_exit;
+ attrib++;
+ break;
+
+ case GLX_ALPHA_SIZE:
+ if (attrib[1] > 8)
+ goto err_exit;
+ attrib++;
+ break;
+
+ case GLX_DEPTH_SIZE:
+ if (attrib[1] > 24)
+ goto err_exit;
+ attrib++;
+ break;
+
+ case GLX_STENCIL_SIZE:
+ if (attrib[1] > 8)
+ goto err_exit;
+ attrib++;
+ break;
+
+ case GLX_ACCUM_RED_SIZE:
+ case GLX_ACCUM_GREEN_SIZE:
+ case GLX_ACCUM_BLUE_SIZE:
+ case GLX_ACCUM_ALPHA_SIZE:
+ if (attrib[1] > 16)
+ goto err_exit;
+ attrib++;
+ break;
+
+ case GLX_SAMPLE_BUFFERS_SGIS: /* aka GLX_SAMPLES_ARB */
+ if (attrib[1] > 0)
+ goto err_exit;
+ attrib++;
+ break;
+ case GLX_SAMPLES_SGIS: /* aka GLX_SAMPLES_ARB */
+ if (attrib[1] > 0)
+ goto err_exit;
+ attrib++;
+ break;
+
+ case GLX_DOUBLEBUFFER: /* @todo, check if we support it */
+ break;
+
+#ifdef GLX_VERSION_1_3
+ case GLX_X_VISUAL_TYPE:
+ case GLX_TRANSPARENT_TYPE_EXT:
+ case GLX_TRANSPARENT_INDEX_VALUE_EXT:
+ case GLX_TRANSPARENT_RED_VALUE_EXT:
+ case GLX_TRANSPARENT_GREEN_VALUE_EXT:
+ case GLX_TRANSPARENT_BLUE_VALUE_EXT:
+ case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
+ /* ignore */
+ crWarning("glXChooseVisual: ignoring attribute 0x%x", *attrib);
+ attrib++;
+ break;
+#endif
+
+ default:
+ crWarning( "glXChooseVisual: bad attrib=0x%x, ignoring", *attrib );
+ attrib++;
+ //return NULL;
+ }
+ }
+
+ if (!useRGBA)
+ return NULL;
+
+ XLOCK(dpy);
+ searchvis.visualid = XVisualIDFromVisual(DefaultVisual(dpy, screen));
+ pret = XGetVisualInfo(dpy, VisualIDMask, &searchvis, &nvisuals);
+ XUNLOCK(dpy);
+
+ if (nvisuals!=1) crWarning("glXChooseVisual: XGetVisualInfo returned %i visuals for %x", nvisuals, (unsigned int) searchvis.visualid);
+ if (pret)
+ crDebug("glXChooseVisual returned %x depth=%i", (unsigned int)pret->visualid, pret->depth);
+ return pret;
+
+err_exit:
+ crDebug("glXChooseVisual returning NULL, due to attrib=0x%x, next=0x%x", attrib[0], attrib[1]);
+ return NULL;
+}
+
+/**
+ ** There is a problem with glXCopyContext.
+ ** IRIX and Mesa both define glXCopyContext
+ ** to have the mask argument being a
+ ** GLuint. XFree 4 and oss.sgi.com
+ ** define it to be an unsigned long.
+ ** Solution: We don't support
+ ** glXCopyContext anyway so we'll just
+ ** \#ifdef out the code.
+ */
+DECLEXPORT(void)
+VBOXGLXTAG(glXCopyContext)( Display *dpy, GLXContext src, GLXContext dst,
+#if defined(AIX) || defined(PLAYSTATION2)
+GLuint mask
+#elif defined(SunOS)
+unsigned long mask
+#else
+unsigned long mask
+#endif
+)
+{
+ (void) dpy;
+ (void) src;
+ (void) dst;
+ (void) mask;
+ crWarning( "Unsupported GLX Call: glXCopyContext()" );
+}
+
+
+/**
+ * Get the display string for the given display pointer.
+ * Never return just ":0.0". In that case, prefix with our host name.
+ */
+static void
+stubGetDisplayString( Display *dpy, char *nameResult, int maxResult )
+{
+ const char *dpyName = DisplayString(dpy);
+ char host[1000];
+
+ host[0] = 0;
+ if (crStrlen(host) + crStrlen(dpyName) >= maxResult - 1)
+ {
+ /* return null string */
+ crWarning("Very long host / display name string in stubDisplayString!");
+ nameResult[0] = 0;
+ }
+ else
+ {
+ /* return host concatenated with dpyName */
+ crStrcpy(nameResult, host);
+ crStrcat(nameResult, dpyName);
+ }
+}
+
+
+
+DECLEXPORT(GLXContext)
+VBOXGLXTAG(glXCreateContext)(Display *dpy, XVisualInfo *vis, GLXContext share, Bool direct)
+{
+ char dpyName[MAX_DPY_NAME];
+ ContextInfo *context;
+ int visBits = CR_RGB_BIT | CR_DOUBLE_BIT | CR_DEPTH_BIT; /* default vis */
+
+ (void)vis;
+ stubInit();
+
+ CRASSERT(stub.contextTable);
+
+ /*
+ {
+ int i, numExt;
+ char **list;
+
+ list = XListExtensions(dpy, &numExt);
+ crDebug("X extensions [%i]:", numExt);
+ for (i=0; i<numExt; ++i)
+ {
+ crDebug("%s", list[i]);
+ }
+ XFreeExtensionList(list);
+ }
+ */
+
+ stubGetDisplayString(dpy, dpyName, MAX_DPY_NAME);
+
+ context = stubNewContext(dpyName, visBits, UNDECIDED, (unsigned long) share);
+ if (!context)
+ return 0;
+
+ context->dpy = dpy;
+ context->direct = direct;
+
+ stubQueryXDamageExtension(dpy, context);
+
+ return (GLXContext) context->id;
+}
+
+
+DECLEXPORT(void) VBOXGLXTAG(glXDestroyContext)( Display *dpy, GLXContext ctx )
+{
+ (void) dpy;
+ stubDestroyContext( (unsigned long) ctx );
+}
+
+typedef struct _stubFindPixmapParms_t {
+ ContextInfo *pCtx;
+ GLX_Pixmap_t *pGlxPixmap;
+ GLXDrawable draw;
+} stubFindPixmapParms_t;
+
+static void stubFindPixmapCB(unsigned long key, void *data1, void *data2)
+{
+ ContextInfo *pCtx = (ContextInfo *) data1;
+ stubFindPixmapParms_t *pParms = (stubFindPixmapParms_t *) data2;
+ GLX_Pixmap_t *pGlxPixmap = (GLX_Pixmap_t *) crHashtableSearch(pCtx->pGLXPixmapsHash, (unsigned int) pParms->draw);
+ (void)key;
+
+ if (pGlxPixmap)
+ {
+ pParms->pCtx = pCtx;
+ pParms->pGlxPixmap = pGlxPixmap;
+ }
+}
+
+DECLEXPORT(Bool) VBOXGLXTAG(glXMakeCurrent)( Display *dpy, GLXDrawable drawable, GLXContext ctx )
+{
+ ContextInfo *context;
+ WindowInfo *window;
+ Bool retVal;
+
+ /*crDebug("glXMakeCurrent(%p, 0x%x, 0x%x)", (void *) dpy, (int) drawable, (int) ctx);*/
+
+ /*check if passed drawable is GLXPixmap and not X Window*/
+ if (drawable)
+ {
+ GLX_Pixmap_t *pGlxPixmap = (GLX_Pixmap_t *) crHashtableSearch(stub.pGLXPixmapsHash, (unsigned int) drawable);
+
+ if (!pGlxPixmap)
+ {
+ stubFindPixmapParms_t parms;
+ parms.pGlxPixmap = NULL;
+ parms.draw = drawable;
+ crHashtableWalk(stub.contextTable, stubFindPixmapCB, &parms);
+ pGlxPixmap = parms.pGlxPixmap;
+ }
+
+ if (pGlxPixmap)
+ {
+ /** @todo */
+ crWarning("Unimplemented glxMakeCurrent call with GLXPixmap passed, unexpected things might happen.");
+ }
+ }
+
+ if (ctx && drawable)
+ {
+ crHashtableLock(stub.windowTable);
+ crHashtableLock(stub.contextTable);
+
+ context = (ContextInfo *) crHashtableSearch(stub.contextTable, (unsigned long) ctx);
+ window = stubGetWindowInfo(dpy, drawable);
+
+ if (context && context->type == UNDECIDED) {
+ XLOCK(dpy);
+ XSync(dpy, 0); /* sync to force window creation on the server */
+ XUNLOCK(dpy);
+ }
+ }
+ else
+ {
+ dpy = NULL;
+ window = NULL;
+ context = NULL;
+ }
+
+ currentDisplay = dpy;
+ currentDrawable = drawable;
+
+ retVal = stubMakeCurrent(window, context);
+
+ if (ctx && drawable)
+ {
+ crHashtableUnlock(stub.contextTable);
+ crHashtableUnlock(stub.windowTable);
+ }
+
+ return retVal;
+}
+
+DECLEXPORT(GLXPixmap) VBOXGLXTAG(glXCreateGLXPixmap)( Display *dpy, XVisualInfo *vis, Pixmap pixmap )
+{
+ stubInit();
+ return VBOXGLXTAG(glXCreatePixmap)(dpy, fbConfigFromVisual(dpy, vis), pixmap, NULL);
+}
+
+DECLEXPORT(void) VBOXGLXTAG(glXDestroyGLXPixmap)( Display *dpy, GLXPixmap pix )
+{
+ VBOXGLXTAG(glXDestroyPixmap)(dpy, pix);
+}
+
+DECLEXPORT(int) VBOXGLXTAG(glXGetConfig)( Display *dpy, XVisualInfo *vis, int attrib, int *value )
+{
+ if (!vis) {
+ /* SGI OpenGL Performer hits this */
+ crWarning("glXGetConfig called with NULL XVisualInfo");
+ return GLX_BAD_VISUAL;
+ }
+
+ stubInit();
+
+ *value = 0; /* For sanity */
+
+ switch ( attrib ) {
+
+ case GLX_USE_GL:
+ *value = isGLXVisual(dpy, vis);
+ break;
+
+ case GLX_BUFFER_SIZE:
+ *value = 32;
+ break;
+
+ case GLX_LEVEL:
+ *value = 0; /* for now */
+ break;
+
+ case GLX_RGBA:
+ *value = 1;
+ break;
+
+ case GLX_DOUBLEBUFFER:
+ *value = 1;
+ break;
+
+ case GLX_STEREO:
+ *value = 1;
+ break;
+
+ case GLX_AUX_BUFFERS:
+ *value = 0;
+ break;
+
+ case GLX_RED_SIZE:
+ *value = 8;
+ break;
+
+ case GLX_GREEN_SIZE:
+ *value = 8;
+ break;
+
+ case GLX_BLUE_SIZE:
+ *value = 8;
+ break;
+
+ case GLX_ALPHA_SIZE:
+ *value = 8;
+ break;
+
+ case GLX_DEPTH_SIZE:
+ *value = 24;
+ break;
+
+ case GLX_STENCIL_SIZE:
+ *value = 8;
+ break;
+
+ case GLX_ACCUM_RED_SIZE:
+ *value = 16;
+ break;
+
+ case GLX_ACCUM_GREEN_SIZE:
+ *value = 16;
+ break;
+
+ case GLX_ACCUM_BLUE_SIZE:
+ *value = 16;
+ break;
+
+ case GLX_ACCUM_ALPHA_SIZE:
+ *value = 16;
+ break;
+
+ case GLX_SAMPLE_BUFFERS_SGIS:
+ *value = 0; /* fix someday */
+ break;
+
+ case GLX_SAMPLES_SGIS:
+ *value = 0; /* fix someday */
+ break;
+
+ case GLX_VISUAL_CAVEAT_EXT:
+ *value = GLX_NONE_EXT;
+ break;
+#if defined(SunOS) || 1
+ /*
+ I don't think this is even a valid attribute for glxGetConfig.
+ No idea why this gets called under SunOS but we simply ignore it
+ -- jw
+ */
+ case GLX_X_VISUAL_TYPE:
+ crWarning ("Ignoring Unsupported GLX Call: glxGetConfig with attrib 0x%x", attrib);
+ break;
+#endif
+
+ case GLX_TRANSPARENT_TYPE:
+ *value = GLX_NONE_EXT;
+ break;
+ case GLX_TRANSPARENT_INDEX_VALUE:
+ *value = 0;
+ break;
+ case GLX_TRANSPARENT_RED_VALUE:
+ *value = 0;
+ break;
+ case GLX_TRANSPARENT_GREEN_VALUE:
+ *value = 0;
+ break;
+ case GLX_TRANSPARENT_BLUE_VALUE:
+ *value = 0;
+ break;
+ case GLX_TRANSPARENT_ALPHA_VALUE:
+ *value = 0;
+ break;
+ case GLX_DRAWABLE_TYPE:
+ *value = GLX_WINDOW_BIT;
+ break;
+ default:
+ crWarning( "Unsupported GLX Call: glXGetConfig with attrib 0x%x, ignoring...", attrib );
+ //return GLX_BAD_ATTRIBUTE;
+ *value = 0;
+ }
+
+ return 0;
+}
+
+DECLEXPORT(GLXContext) VBOXGLXTAG(glXGetCurrentContext)( void )
+{
+ ContextInfo *context = stubGetCurrentContext();
+ if (context)
+ return (GLXContext) context->id;
+ else
+ return (GLXContext) NULL;
+}
+
+DECLEXPORT(GLXDrawable) VBOXGLXTAG(glXGetCurrentDrawable)(void)
+{
+ return currentDrawable;
+}
+
+DECLEXPORT(Display *) VBOXGLXTAG(glXGetCurrentDisplay)(void)
+{
+ return currentDisplay;
+}
+
+DECLEXPORT(Bool) VBOXGLXTAG(glXIsDirect)(Display *dpy, GLXContext ctx)
+{
+ (void) dpy;
+ (void) ctx;
+ crDebug("->glXIsDirect");
+ return True;
+}
+
+DECLEXPORT(Bool) VBOXGLXTAG(glXQueryExtension)(Display *dpy, int *errorBase, int *eventBase)
+{
+ (void) dpy;
+ (void) errorBase;
+ (void) eventBase;
+ return 1; /* You BET we do... */
+}
+
+DECLEXPORT(Bool) VBOXGLXTAG(glXQueryVersion)( Display *dpy, int *major, int *minor )
+{
+ (void) dpy;
+ *major = 1;
+ *minor = 3;
+ return 1;
+}
+
+DECLEXPORT(void) VBOXGLXTAG(glXSwapBuffers)( Display *dpy, GLXDrawable drawable )
+{
+ WindowInfo *window = stubGetWindowInfo(dpy, drawable);
+ stubSwapBuffers( window, 0 );
+}
+
+DECLEXPORT(void) VBOXGLXTAG(glXUseXFont)( Font font, int first, int count, int listBase )
+{
+ ContextInfo *context = stubGetCurrentContext();
+ Display *dpy = context->dpy;
+ if (dpy) {
+ stubUseXFont( dpy, font, first, count, listBase );
+ }
+ else {
+ dpy = XOpenDisplay(NULL);
+ if (!dpy)
+ return;
+ stubUseXFont( dpy, font, first, count, listBase );
+ XCloseDisplay(dpy);
+ }
+}
+
+DECLEXPORT(void) VBOXGLXTAG(glXWaitGL)( void )
+{
+ static int first_call = 1;
+
+ if ( first_call )
+ {
+ crDebug( "Ignoring unsupported GLX call: glXWaitGL()" );
+ first_call = 0;
+ }
+}
+
+DECLEXPORT(void) VBOXGLXTAG(glXWaitX)( void )
+{
+ static int first_call = 1;
+
+ if ( first_call )
+ {
+ crDebug( "Ignoring unsupported GLX call: glXWaitX()" );
+ first_call = 0;
+ }
+}
+
+DECLEXPORT(const char *) VBOXGLXTAG(glXQueryExtensionsString)( Display *dpy, int screen )
+{
+ /* XXX maybe also advertise GLX_SGIS_multisample? */
+
+ static const char *retval = "GLX_ARB_multisample GLX_EXT_texture_from_pixmap GLX_SGIX_fbconfig GLX_ARB_get_proc_address";
+
+ (void) dpy;
+ (void) screen;
+
+ crDebug("->glXQueryExtensionsString");
+ return retval;
+}
+
+DECLEXPORT(const char *) VBOXGLXTAG(glXGetClientString)( Display *dpy, int name )
+{
+ const char *retval;
+ (void) dpy;
+ (void) name;
+
+ switch ( name ) {
+
+ case GLX_VENDOR:
+ retval = "Chromium";
+ break;
+
+ case GLX_VERSION:
+ retval = "1.3 Chromium";
+ break;
+
+ case GLX_EXTENSIONS:
+ /** @todo should be a screen not a name...but it's not used anyway*/
+ retval = glXQueryExtensionsString(dpy, name);
+ break;
+
+ default:
+ retval = NULL;
+ }
+
+ return retval;
+}
+
+DECLEXPORT(const char *) VBOXGLXTAG(glXQueryServerString)( Display *dpy, int screen, int name )
+{
+ const char *retval;
+ (void) dpy;
+ (void) screen;
+
+ switch ( name ) {
+
+ case GLX_VENDOR:
+ retval = "Chromium";
+ break;
+
+ case GLX_VERSION:
+ retval = "1.3 Chromium";
+ break;
+
+ case GLX_EXTENSIONS:
+ retval = glXQueryExtensionsString(dpy, screen);
+ break;
+
+ default:
+ retval = NULL;
+ }
+
+ return retval;
+}
+
+DECLEXPORT(CR_GLXFuncPtr) VBOXGLXTAG(glXGetProcAddressARB)( const GLubyte *name )
+{
+ return (CR_GLXFuncPtr) crGetProcAddress( (const char *) name );
+}
+
+DECLEXPORT(CR_GLXFuncPtr) VBOXGLXTAG(glXGetProcAddress)( const GLubyte *name )
+{
+ return (CR_GLXFuncPtr) crGetProcAddress( (const char *) name );
+}
+
+
+#if GLX_EXTRAS
+
+DECLEXPORT(GLXPbufferSGIX)
+VBOXGLXTAG(glXCreateGLXPbufferSGIX)(Display *dpy, GLXFBConfigSGIX config,
+ unsigned int width, unsigned int height,
+ int *attrib_list)
+{
+ (void) dpy;
+ (void) config;
+ (void) width;
+ (void) height;
+ (void) attrib_list;
+ crWarning("glXCreateGLXPbufferSGIX not implemented by Chromium");
+ return 0;
+}
+
+DECLEXPORT(void) VBOXGLXTAG(glXDestroyGLXPbufferSGIX)(Display *dpy, GLXPbuffer pbuf)
+{
+ (void) dpy;
+ (void) pbuf;
+ crWarning("glXDestroyGLXPbufferSGIX not implemented by Chromium");
+}
+
+DECLEXPORT(void) VBOXGLXTAG(glXSelectEventSGIX)(Display *dpy, GLXDrawable drawable, unsigned long mask)
+{
+ (void) dpy;
+ (void) drawable;
+ (void) mask;
+}
+
+DECLEXPORT(void) VBOXGLXTAG(glXGetSelectedEventSGIX)(Display *dpy, GLXDrawable drawable, unsigned long *mask)
+{
+ (void) dpy;
+ (void) drawable;
+ (void) mask;
+}
+
+DECLEXPORT(int) VBOXGLXTAG(glXQueryGLXPbufferSGIX)(Display *dpy, GLXPbuffer pbuf,
+ int attribute, unsigned int *value)
+{
+ (void) dpy;
+ (void) pbuf;
+ (void) attribute;
+ (void) value;
+ crWarning("glXQueryGLXPbufferSGIX not implemented by Chromium");
+ return 0;
+}
+
+DECLEXPORT(int) VBOXGLXTAG(glXGetFBConfigAttribSGIX)(Display *dpy, GLXFBConfig config,
+ int attribute, int *value)
+{
+ return VBOXGLXTAG(glXGetFBConfigAttrib)(dpy, config, attribute, value);
+}
+
+DECLEXPORT(GLXFBConfigSGIX *)
+VBOXGLXTAG(glXChooseFBConfigSGIX)(Display *dpy, int screen,
+ int *attrib_list, int *nelements)
+{
+ return VBOXGLXTAG(glXChooseFBConfig)(dpy, screen, attrib_list, nelements);
+}
+
+DECLEXPORT(GLXPixmap)
+VBOXGLXTAG(glXCreateGLXPixmapWithConfigSGIX)(Display *dpy,
+ GLXFBConfig config,
+ Pixmap pixmap)
+{
+ return VBOXGLXTAG(glXCreatePixmap)(dpy, config, pixmap, NULL);
+}
+
+DECLEXPORT(GLXContext)
+VBOXGLXTAG(glXCreateContextWithConfigSGIX)(Display *dpy, GLXFBConfig config,
+ int render_type,
+ GLXContext share_list,
+ Bool direct)
+{
+ (void)config;
+ if (render_type!=GLX_RGBA_TYPE_SGIX)
+ {
+ crWarning("glXCreateContextWithConfigSGIX: Unsupported render type %i", render_type);
+ return NULL;
+ }
+ return VBOXGLXTAG(glXCreateContext)(dpy, NULL, share_list, direct);
+}
+
+DECLEXPORT(XVisualInfo *)
+VBOXGLXTAG(glXGetVisualFromFBConfigSGIX)(Display *dpy,
+ GLXFBConfig config)
+{
+ return visualInfoFromFBConfig(dpy, config);
+}
+
+DECLEXPORT(GLXFBConfigSGIX)
+VBOXGLXTAG(glXGetFBConfigFromVisualSGIX)(Display *dpy, XVisualInfo *vis)
+{
+ if (!vis)
+ {
+ return NULL;
+ }
+ /*Note: Caller is supposed to call XFree on returned value, so can't just return (GLXFBConfig)vis->visualid*/
+ return (GLXFBConfigSGIX) visualInfoFromFBConfig(dpy, fbConfigFromVisual(dpy, vis));
+}
+
+/*
+ * GLX 1.3 functions
+ */
+DECLEXPORT(GLXFBConfig *)
+VBOXGLXTAG(glXChooseFBConfig)(Display *dpy, int screen, ATTRIB_TYPE *attrib_list, int *nelements)
+{
+ ATTRIB_TYPE *attrib;
+ intptr_t fbconfig = 0;
+
+ stubInit();
+
+ if (!attrib_list)
+ {
+ return VBOXGLXTAG(glXGetFBConfigs)(dpy, screen, nelements);
+ }
+
+ for (attrib = attrib_list; *attrib != None; attrib++)
+ {
+ switch (*attrib)
+ {
+ case GLX_FBCONFIG_ID:
+ fbconfig = attrib[1];
+ attrib++;
+ break;
+
+ case GLX_BUFFER_SIZE:
+ /* this is ignored except for color-index visuals, which we don't support */
+ attrib++;
+ break;
+
+ case GLX_LEVEL:
+ if (attrib[1] != 0)
+ goto err_exit;
+ attrib++;
+ break;
+
+ case GLX_AUX_BUFFERS:
+ if (attrib[1] != 0)
+ goto err_exit;
+ attrib++;
+ break;
+
+ case GLX_DOUBLEBUFFER: /* @todo, check if we support it */
+ attrib++;
+ break;
+
+ case GLX_STEREO:
+ if (attrib[1] != 0)
+ goto err_exit;
+ attrib++;
+ break;
+
+ case GLX_RED_SIZE:
+ case GLX_GREEN_SIZE:
+ case GLX_BLUE_SIZE:
+ case GLX_ALPHA_SIZE:
+ if (attrib[1] > 8)
+ goto err_exit;
+ attrib++;
+ break;
+
+ case GLX_DEPTH_SIZE:
+ if (attrib[1] > 24)
+ goto err_exit;
+ attrib++;
+ break;
+
+ case GLX_STENCIL_SIZE:
+ if (attrib[1] > 8)
+ goto err_exit;
+ attrib++;
+ break;
+
+ case GLX_ACCUM_RED_SIZE:
+ case GLX_ACCUM_GREEN_SIZE:
+ case GLX_ACCUM_BLUE_SIZE:
+ case GLX_ACCUM_ALPHA_SIZE:
+ if (attrib[1] > 16)
+ goto err_exit;
+ attrib++;
+ break;
+
+ case GLX_X_RENDERABLE:
+ case GLX_CONFIG_CAVEAT:
+ attrib++;
+ break;
+
+ case GLX_RENDER_TYPE:
+ if (attrib[1]!=GLX_RGBA_BIT)
+ goto err_exit;
+ attrib++;
+ break;
+
+ case GLX_DRAWABLE_TYPE:
+ if ( !(attrib[1] & GLX_WINDOW_BIT)
+ && !(attrib[1] & GLX_PIXMAP_BIT))
+ goto err_exit;
+ attrib++;
+ break;
+
+ case GLX_X_VISUAL_TYPE:
+ case GLX_TRANSPARENT_TYPE_EXT:
+ case GLX_TRANSPARENT_INDEX_VALUE_EXT:
+ case GLX_TRANSPARENT_RED_VALUE_EXT:
+ case GLX_TRANSPARENT_GREEN_VALUE_EXT:
+ case GLX_TRANSPARENT_BLUE_VALUE_EXT:
+ case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
+ /* ignore */
+ crWarning("glXChooseVisual: ignoring attribute 0x%x", *attrib);
+ attrib++;
+ break;
+
+ break;
+ default:
+ crWarning( "glXChooseVisual: bad attrib=0x%x, ignoring", *attrib );
+ attrib++;
+ break;
+ }
+ }
+
+ if (fbconfig)
+ {
+ GLXFBConfig *pGLXFBConfigs;
+
+ *nelements = 1;
+ pGLXFBConfigs = (GLXFBConfig *) crAlloc(*nelements * sizeof(GLXFBConfig));
+ pGLXFBConfigs[0] = (GLXFBConfig)fbconfig;
+ return pGLXFBConfigs;
+ }
+ else
+ {
+ return VBOXGLXTAG(glXGetFBConfigs)(dpy, screen, nelements);
+ }
+
+err_exit:
+ crWarning("glXChooseFBConfig returning NULL, due to attrib=0x%x, next=0x%x", attrib[0], attrib[1]);
+ return NULL;
+}
+
+DECLEXPORT(GLXContext)
+VBOXGLXTAG(glXCreateNewContext)(Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct)
+{
+ (void) dpy;
+ (void) config;
+ (void) render_type;
+ (void) share_list;
+ (void) direct;
+
+ if (render_type != GLX_RGBA_TYPE)
+ {
+ crWarning("glXCreateNewContext, unsupported render_type %x", render_type);
+ return NULL;
+ }
+
+ return VBOXGLXTAG(glXCreateContext)(dpy, NULL, share_list, direct);
+}
+
+DECLEXPORT(GLXPbuffer)
+VBOXGLXTAG(glXCreatePbuffer)(Display *dpy, GLXFBConfig config, ATTRIB_TYPE *attrib_list)
+{
+ (void) dpy;
+ (void) config;
+ (void) attrib_list;
+ crWarning("glXCreatePbuffer not implemented by Chromium");
+ return 0;
+}
+
+/* Note: there're examples where glxpixmaps are created without current context, so can't do much of the work here.
+ * Instead we'd do necessary initialization on first use of those pixmaps.
+ */
+DECLEXPORT(GLXPixmap)
+VBOXGLXTAG(glXCreatePixmap)(Display *dpy, GLXFBConfig config, Pixmap pixmap, ATTRIB_TYPE *attrib_list)
+{
+ ATTRIB_TYPE *attrib;
+ GLX_Pixmap_t *pGlxPixmap;
+ (void) dpy;
+ (void) config;
+
+#if 0
+ {
+ int x, y;
+ unsigned int w, h;
+ unsigned int border;
+ unsigned int depth;
+ Window root;
+
+ crDebug("glXCreatePixmap called for %lu", pixmap);
+
+ XLOCK(dpy);
+ if (!XGetGeometry(dpy, pixmap, &root, &x, &y, &w, &h, &border, &depth))
+ {
+ XSync(dpy, False);
+ if (!XGetGeometry(dpy, pixmap, &root, &x, &y, &w, &h, &border, &depth))
+ {
+ crDebug("fail");
+ }
+ }
+ crDebug("root: %lu, [%i,%i %u,%u]", root, x, y, w, h);
+ XUNLOCK(dpy);
+ }
+#endif
+
+ pGlxPixmap = crCalloc(sizeof(GLX_Pixmap_t));
+ if (!pGlxPixmap)
+ {
+ crWarning("glXCreatePixmap failed to allocate memory");
+ return 0;
+ }
+
+ pGlxPixmap->format = GL_RGBA;
+ pGlxPixmap->target = GL_TEXTURE_2D;
+
+ if (attrib_list)
+ {
+ for (attrib = attrib_list; *attrib != None; attrib++)
+ {
+ switch (*attrib)
+ {
+ case GLX_TEXTURE_FORMAT_EXT:
+ attrib++;
+ switch (*attrib)
+ {
+ case GLX_TEXTURE_FORMAT_RGBA_EXT:
+ pGlxPixmap->format = GL_RGBA;
+ break;
+ case GLX_TEXTURE_FORMAT_RGB_EXT:
+ pGlxPixmap->format = GL_RGB;
+ break;
+ default:
+ crDebug("Unexpected GLX_TEXTURE_FORMAT_EXT 0x%x", (unsigned int) *attrib);
+ }
+ break;
+ case GLX_TEXTURE_TARGET_EXT:
+ attrib++;
+ switch (*attrib)
+ {
+ case GLX_TEXTURE_2D_EXT:
+ pGlxPixmap->target = GL_TEXTURE_2D;
+ break;
+ case GLX_TEXTURE_RECTANGLE_EXT:
+ pGlxPixmap->target = GL_TEXTURE_RECTANGLE_NV;
+ break;
+ default:
+ crDebug("Unexpected GLX_TEXTURE_TARGET_EXT 0x%x", (unsigned int) *attrib);
+ }
+ break;
+ default: attrib++;
+ }
+ }
+ }
+
+ crHashtableAdd(stub.pGLXPixmapsHash, (unsigned int) pixmap, pGlxPixmap);
+ return (GLXPixmap) pixmap;
+}
+
+DECLEXPORT(GLXWindow)
+VBOXGLXTAG(glXCreateWindow)(Display *dpy, GLXFBConfig config, Window win, ATTRIB_TYPE *attrib_list)
+{
+ GLXFBConfig *realcfg;
+ int nconfigs;
+ (void) config;
+
+ if (stub.wsInterface.glXGetFBConfigs)
+ {
+ realcfg = stub.wsInterface.glXGetFBConfigs(dpy, 0, &nconfigs);
+ if (!realcfg || nconfigs<1)
+ {
+ crWarning("glXCreateWindow !realcfg || nconfigs<1");
+ return 0;
+ }
+ else
+ {
+ return stub.wsInterface.glXCreateWindow(dpy, realcfg[0], win, attrib_list);
+ }
+ }
+ else
+ {
+ if (attrib_list && *attrib_list!=None)
+ {
+ crWarning("Non empty attrib list in glXCreateWindow");
+ return 0;
+ }
+ return (GLXWindow)win;
+ }
+}
+
+DECLEXPORT(void) VBOXGLXTAG(glXDestroyPbuffer)(Display *dpy, GLXPbuffer pbuf)
+{
+ (void) dpy;
+ (void) pbuf;
+ crWarning("glXDestroyPbuffer not implemented by Chromium");
+}
+
+DECLEXPORT(void) VBOXGLXTAG(glXDestroyPixmap)(Display *dpy, GLXPixmap pixmap)
+{
+ stubFindPixmapParms_t parms;
+
+ if (crHashtableSearch(stub.pGLXPixmapsHash, (unsigned int) pixmap))
+ {
+ /*it's valid but never used glxpixmap, so simple free stored ptr*/
+ crHashtableDelete(stub.pGLXPixmapsHash, (unsigned int) pixmap, crFree);
+ return;
+ }
+ else
+ {
+ /*it's either invalid glxpixmap or one which was already initialized, so it's stored in appropriate ctx hash*/
+ parms.pCtx = NULL;
+ parms.pGlxPixmap = NULL;
+ parms.draw = pixmap;
+ crHashtableWalk(stub.contextTable, stubFindPixmapCB, &parms);
+ }
+
+ if (!parms.pGlxPixmap)
+ {
+ crWarning("glXDestroyPixmap called for unknown glxpixmap 0x%x", (unsigned int) pixmap);
+ return;
+ }
+
+ XLOCK(dpy);
+ if (parms.pGlxPixmap->gc)
+ {
+ XFreeGC(dpy, parms.pGlxPixmap->gc);
+ }
+
+ if (parms.pGlxPixmap->hShmPixmap>0)
+ {
+ XFreePixmap(dpy, parms.pGlxPixmap->hShmPixmap);
+ }
+ XUNLOCK(dpy);
+
+ if (parms.pGlxPixmap->hDamage>0)
+ {
+ //crDebug("Destroy: Damage for drawable 0x%x, handle 0x%x", (unsigned int) pixmap, (unsigned int) parms.pGlxPixmap->damage);
+ XDamageDestroy(dpy, parms.pGlxPixmap->hDamage);
+ }
+
+ if (parms.pGlxPixmap->pDamageRegion)
+ {
+ XDestroyRegion(parms.pGlxPixmap->pDamageRegion);
+ }
+
+ crHashtableDelete(parms.pCtx->pGLXPixmapsHash, (unsigned int) pixmap, crFree);
+}
+
+DECLEXPORT(void) VBOXGLXTAG(glXDestroyWindow)(Display *dpy, GLXWindow win)
+{
+ (void) dpy;
+ (void) win;
+ /*crWarning("glXDestroyWindow not implemented by Chromium");*/
+}
+
+DECLEXPORT(GLXDrawable) VBOXGLXTAG(glXGetCurrentReadDrawable)(void)
+{
+ return currentReadDrawable;
+}
+
+DECLEXPORT(int) VBOXGLXTAG(glXGetFBConfigAttrib)(Display *dpy, GLXFBConfig config, int attribute, int *value)
+{
+ XVisualInfo * pVisual;
+ const char * pExt;
+
+ switch (attribute)
+ {
+ case GLX_DRAWABLE_TYPE:
+ *value = GLX_PIXMAP_BIT | GLX_WINDOW_BIT;
+ break;
+ case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
+ *value = GLX_TEXTURE_2D_BIT_EXT;
+ pExt = (const char *) stub.spu->dispatch_table.GetString(GL_EXTENSIONS);
+ if (crStrstr(pExt, "GL_NV_texture_rectangle")
+ || crStrstr(pExt, "GL_ARB_texture_rectangle")
+ || crStrstr(pExt, "GL_EXT_texture_rectangle"))
+ {
+ *value |= GLX_TEXTURE_RECTANGLE_BIT_EXT;
+ }
+ break;
+ case GLX_BIND_TO_TEXTURE_RGBA_EXT:
+ *value = True;
+ break;
+ case GLX_BIND_TO_TEXTURE_RGB_EXT:
+ *value = True;
+ break;
+ case GLX_DOUBLEBUFFER:
+ //crDebug("attribute=GLX_DOUBLEBUFFER");
+ *value = True;
+ break;
+ case GLX_Y_INVERTED_EXT:
+ *value = True;
+ break;
+ case GLX_ALPHA_SIZE:
+ //crDebug("attribute=GLX_ALPHA_SIZE");
+ *value = 8;
+ break;
+ case GLX_BUFFER_SIZE:
+ //crDebug("attribute=GLX_BUFFER_SIZE");
+ *value = 32;
+ break;
+ case GLX_STENCIL_SIZE:
+ //crDebug("attribute=GLX_STENCIL_SIZE");
+ *value = 8;
+ break;
+ case GLX_DEPTH_SIZE:
+ *value = 24;
+ //crDebug("attribute=GLX_DEPTH_SIZE");
+ break;
+ case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
+ *value = 0;
+ break;
+ case GLX_RENDER_TYPE:
+ //crDebug("attribute=GLX_RENDER_TYPE");
+ *value = GLX_RGBA_BIT;
+ break;
+ case GLX_CONFIG_CAVEAT:
+ //crDebug("attribute=GLX_CONFIG_CAVEAT");
+ *value = GLX_NONE;
+ break;
+ case GLX_VISUAL_ID:
+ //crDebug("attribute=GLX_VISUAL_ID");
+ pVisual = visualInfoFromFBConfig(dpy, config);
+ if (!pVisual)
+ {
+ crWarning("glXGetFBConfigAttrib for %p, failed to get XVisualInfo", config);
+ return GLX_BAD_ATTRIBUTE;
+ }
+ *value = pVisual->visualid;
+ XFree(pVisual);
+ break;
+ case GLX_FBCONFIG_ID:
+ *value = (int)(intptr_t)config;
+ break;
+ case GLX_RED_SIZE:
+ case GLX_GREEN_SIZE:
+ case GLX_BLUE_SIZE:
+ *value = 8;
+ break;
+ case GLX_LEVEL:
+ *value = 0;
+ break;
+ case GLX_STEREO:
+ *value = false;
+ break;
+ case GLX_AUX_BUFFERS:
+ *value = 0;
+ break;
+ case GLX_ACCUM_RED_SIZE:
+ case GLX_ACCUM_GREEN_SIZE:
+ case GLX_ACCUM_BLUE_SIZE:
+ case GLX_ACCUM_ALPHA_SIZE:
+ *value = 0;
+ break;
+ case GLX_X_VISUAL_TYPE:
+ *value = GLX_TRUE_COLOR;
+ break;
+ case GLX_TRANSPARENT_TYPE:
+ *value = GLX_NONE;
+ break;
+ case GLX_SAMPLE_BUFFERS:
+ case GLX_SAMPLES:
+ *value = 1;
+ break;
+ case GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT:
+ *value = 0;
+ break;
+ default:
+ crDebug("glXGetFBConfigAttrib: unknown attribute=0x%x", attribute);
+ return GLX_BAD_ATTRIBUTE;
+ }
+
+ return Success;
+}
+
+DECLEXPORT(GLXFBConfig *) VBOXGLXTAG(glXGetFBConfigs)(Display *dpy, int screen, int *nelements)
+{
+ int i;
+
+ GLXFBConfig *pGLXFBConfigs = crAlloc(sizeof(GLXFBConfig));
+
+ *nelements = 1;
+ XLOCK(dpy);
+ *pGLXFBConfigs = defaultFBConfigForScreen(dpy, screen);
+ XUNLOCK(dpy);
+
+ crDebug("glXGetFBConfigs returned %i configs", *nelements);
+ for (i=0; i<*nelements; ++i)
+ {
+ crDebug("glXGetFBConfigs[%i]=0x%x", i, (unsigned)(uintptr_t) pGLXFBConfigs[i]);
+ }
+ return pGLXFBConfigs;
+}
+
+DECLEXPORT(void) VBOXGLXTAG(glXGetSelectedEvent)(Display *dpy, GLXDrawable draw, unsigned long *event_mask)
+{
+ (void) dpy;
+ (void) draw;
+ (void) event_mask;
+ crWarning("glXGetSelectedEvent not implemented by Chromium");
+}
+
+DECLEXPORT(XVisualInfo *) VBOXGLXTAG(glXGetVisualFromFBConfig)(Display *dpy, GLXFBConfig config)
+{
+ return visualInfoFromFBConfig(dpy, config);
+}
+
+DECLEXPORT(Bool) VBOXGLXTAG(glXMakeContextCurrent)(Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
+{
+ currentReadDrawable = read;
+ return VBOXGLXTAG(glXMakeCurrent)(display, draw, ctx);
+}
+
+DECLEXPORT(int) VBOXGLXTAG(glXQueryContext)(Display *dpy, GLXContext ctx, int attribute, int *value)
+{
+ (void) dpy;
+ (void) ctx;
+ (void) attribute;
+ (void) value;
+ crWarning("glXQueryContext not implemented by Chromium");
+ return 0;
+}
+
+DECLEXPORT(void) VBOXGLXTAG(glXQueryDrawable)(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value)
+{
+ (void) dpy;
+ (void) draw;
+ (void) attribute;
+ (void) value;
+ crWarning("glXQueryDrawable not implemented by Chromium");
+}
+
+DECLEXPORT(void) VBOXGLXTAG(glXSelectEvent)(Display *dpy, GLXDrawable draw, unsigned long event_mask)
+{
+ (void) dpy;
+ (void) draw;
+ (void) event_mask;
+ crWarning("glXSelectEvent not implemented by Chromium");
+}
+
+#ifdef CR_EXT_texture_from_pixmap
+/*typedef struct
+{
+ int x, y;
+ unsigned int w, h, border, depth;
+ Window root;
+ void *data;
+} pminfo;*/
+
+static void stubInitXSharedMemory(Display *dpy)
+{
+ int vma, vmi;
+ Bool pixmaps;
+
+ if (stub.bShmInitFailed || stub.xshmSI.shmid>=0)
+ return;
+
+ stub.bShmInitFailed = GL_TRUE;
+
+ /* Check for extension and pixmaps format */
+ XLOCK(dpy);
+ if (!XShmQueryExtension(dpy))
+ {
+ crWarning("No XSHM extension");
+ XUNLOCK(dpy);
+ return;
+ }
+
+ if (!XShmQueryVersion(dpy, &vma, &vmi, &pixmaps) || !pixmaps)
+ {
+ crWarning("XSHM extension doesn't support pixmaps");
+ XUNLOCK(dpy);
+ return;
+ }
+
+ if (XShmPixmapFormat(dpy)!=ZPixmap)
+ {
+ crWarning("XSHM extension doesn't support ZPixmap format");
+ XUNLOCK(dpy);
+ return;
+ }
+ XUNLOCK(dpy);
+
+ /* Alloc shared memory, so far using hardcoded value...could fail for bigger displays one day */
+ stub.xshmSI.readOnly = false;
+ stub.xshmSI.shmid = shmget(IPC_PRIVATE, 4*4096*2048, IPC_CREAT | 0600);
+ if (stub.xshmSI.shmid<0)
+ {
+ crWarning("XSHM Failed to create shared segment");
+ return;
+ }
+
+ stub.xshmSI.shmaddr = (char*) shmat(stub.xshmSI.shmid, NULL, 0);
+ if (stub.xshmSI.shmaddr==(void*)-1)
+ {
+ crWarning("XSHM Failed to attach shared segment");
+ shmctl(stub.xshmSI.shmid, IPC_RMID, 0);
+ return;
+ }
+
+ XLOCK(dpy);
+ if (!XShmAttach(dpy, &stub.xshmSI))
+ {
+ crWarning("XSHM Failed to attach shared segment to XServer");
+ shmctl(stub.xshmSI.shmid, IPC_RMID, 0);
+ shmdt(stub.xshmSI.shmaddr);
+ XUNLOCK(dpy);
+ return;
+ }
+ XUNLOCK(dpy);
+
+ stub.bShmInitFailed = GL_FALSE;
+ crInfo("Using XSHM for GLX_EXT_texture_from_pixmap");
+
+ /*Anyway mark to be deleted when our process detaches it, in case of segfault etc*/
+
+/* Ramshankar: Solaris compiz fix */
+#ifndef RT_OS_SOLARIS
+ shmctl(stub.xshmSI.shmid, IPC_RMID, 0);
+#endif
+}
+
+void stubQueryXDamageExtension(Display *dpy, ContextInfo *pContext)
+{
+ int erb, vma, vmi;
+
+ CRASSERT(pContext);
+
+ if (pContext->damageQueryFailed)
+ return;
+
+ pContext->damageQueryFailed = True;
+
+ if (!XDamageQueryExtension(dpy, &pContext->damageEventsBase, &erb)
+ || !XDamageQueryVersion(dpy, &vma, &vmi))
+ {
+ crWarning("XDamage not found or old version (%i.%i), going to run *very* slow", vma, vmi);
+ return;
+ }
+
+ crDebug("XDamage %i.%i", vma, vmi);
+ pContext->damageQueryFailed = False;
+}
+
+static void stubFetchDamageOnDrawable(Display *dpy, GLX_Pixmap_t *pGlxPixmap)
+{
+ Damage damage = pGlxPixmap->hDamage;
+
+ if (damage)
+ {
+ XRectangle *returnRects;
+ int nReturnRects;
+
+ /* Get the damage region as a server region */
+ XserverRegion serverDamageRegion = XFixesCreateRegion (dpy, NULL, 0);
+
+ /* Unite damage region with server region and clear damage region */
+ XDamageSubtract (dpy,
+ damage,
+ None, /* subtract all damage from this region */
+ serverDamageRegion /* save in serverDamageRegion */);
+
+ /* Fetch damage rectangles */
+ returnRects = XFixesFetchRegion (dpy, serverDamageRegion, &nReturnRects);
+
+ /* Delete region */
+ XFixesDestroyRegion (dpy, serverDamageRegion);
+
+ if (pGlxPixmap->pDamageRegion)
+ {
+ /* If it's dirty and regions are empty, it marked for full update, so do nothing.*/
+ if (!pGlxPixmap->bPixmapImageDirty || !XEmptyRegion(pGlxPixmap->pDamageRegion))
+ {
+ int i = 0;
+ for (; i < nReturnRects; ++i)
+ {
+ if (CR_MAX_DAMAGE_REGIONS_TRACKED <= pGlxPixmap->pDamageRegion->numRects)
+ {
+ /* Mark for full update */
+ EMPTY_REGION(pGlxPixmap->pDamageRegion);
+ }
+ else
+ {
+ /* Add to damage regions */
+ XUnionRectWithRegion(&returnRects[i], pGlxPixmap->pDamageRegion, pGlxPixmap->pDamageRegion);
+ }
+ }
+ }
+ }
+
+ XFree(returnRects);
+
+ pGlxPixmap->bPixmapImageDirty = True;
+ }
+}
+
+static const CRPixelPackState defaultPacking =
+{
+ 0, /*rowLength*/
+ 0, /*skipRows*/
+ 0, /*skipPixels*/
+ 1, /*alignment*/
+ 0, /*imageHeight*/
+ 0, /*skipImages*/
+ GL_FALSE, /*swapBytes*/
+ GL_FALSE /*lsbFirst*/
+};
+
+static void stubGetUnpackState(CRPixelPackState *pUnpackState)
+{
+ stub.spu->dispatch_table.GetIntegerv(GL_UNPACK_ROW_LENGTH, &pUnpackState->rowLength);
+ stub.spu->dispatch_table.GetIntegerv(GL_UNPACK_SKIP_ROWS, &pUnpackState->skipRows);
+ stub.spu->dispatch_table.GetIntegerv(GL_UNPACK_SKIP_PIXELS, &pUnpackState->skipPixels);
+ stub.spu->dispatch_table.GetIntegerv(GL_UNPACK_ALIGNMENT, &pUnpackState->alignment);
+ stub.spu->dispatch_table.GetBooleanv(GL_UNPACK_SWAP_BYTES, &pUnpackState->swapBytes);
+ stub.spu->dispatch_table.GetBooleanv(GL_UNPACK_LSB_FIRST, &pUnpackState->psLSBFirst);
+}
+
+static void stubSetUnpackState(const CRPixelPackState *pUnpackState)
+{
+ stub.spu->dispatch_table.PixelStorei(GL_UNPACK_ROW_LENGTH, pUnpackState->rowLength);
+ stub.spu->dispatch_table.PixelStorei(GL_UNPACK_SKIP_ROWS, pUnpackState->skipRows);
+ stub.spu->dispatch_table.PixelStorei(GL_UNPACK_SKIP_PIXELS, pUnpackState->skipPixels);
+ stub.spu->dispatch_table.PixelStorei(GL_UNPACK_ALIGNMENT, pUnpackState->alignment);
+ stub.spu->dispatch_table.PixelStorei(GL_UNPACK_SWAP_BYTES, pUnpackState->swapBytes);
+ stub.spu->dispatch_table.PixelStorei(GL_UNPACK_LSB_FIRST, pUnpackState->psLSBFirst);
+}
+
+static GLX_Pixmap_t* stubInitGlxPixmap(GLX_Pixmap_t* pCreateInfoPixmap, Display *dpy, GLXDrawable draw, ContextInfo *pContext)
+{
+ int x, y;
+ unsigned int w, h;
+ unsigned int border;
+ unsigned int depth;
+ Window root;
+ GLX_Pixmap_t *pGlxPixmap;
+
+ CRASSERT(pContext && pCreateInfoPixmap);
+
+ XLOCK(dpy);
+ if (!XGetGeometry(dpy, (Pixmap)draw, &root, &x, &y, &w, &h, &border, &depth))
+ {
+ XSync(dpy, False);
+ if (!XGetGeometry(dpy, (Pixmap)draw, &root, &x, &y, &w, &h, &border, &depth))
+ {
+ crWarning("stubInitGlxPixmap failed in call to XGetGeometry for 0x%x", (int) draw);
+ XUNLOCK(dpy);
+ return NULL;
+ }
+ }
+
+ pGlxPixmap = crAlloc(sizeof(GLX_Pixmap_t));
+ if (!pGlxPixmap)
+ {
+ crWarning("stubInitGlxPixmap failed to allocate memory");
+ XUNLOCK(dpy);
+ return NULL;
+ }
+
+ pGlxPixmap->x = x;
+ pGlxPixmap->y = y;
+ pGlxPixmap->w = w;
+ pGlxPixmap->h = h;
+ pGlxPixmap->border = border;
+ pGlxPixmap->depth = depth;
+ pGlxPixmap->root = root;
+ pGlxPixmap->format = pCreateInfoPixmap->format;
+ pGlxPixmap->target = pCreateInfoPixmap->target;
+
+ /* Try to allocate shared memory
+ * As we're allocating huge chunk of memory, do it in this function, only if this extension is really used
+ */
+ if (!stub.bShmInitFailed && stub.xshmSI.shmid<0)
+ {
+ stubInitXSharedMemory(dpy);
+ }
+
+ if (stub.xshmSI.shmid>=0)
+ {
+ XGCValues xgcv;
+ xgcv.graphics_exposures = False;
+ xgcv.subwindow_mode = IncludeInferiors;
+ pGlxPixmap->gc = XCreateGC(dpy, (Pixmap)draw, GCGraphicsExposures|GCSubwindowMode, &xgcv);
+
+ pGlxPixmap->hShmPixmap = XShmCreatePixmap(dpy, pGlxPixmap->root, stub.xshmSI.shmaddr, &stub.xshmSI,
+ pGlxPixmap->w, pGlxPixmap->h, pGlxPixmap->depth);
+ }
+ else
+ {
+ pGlxPixmap->gc = NULL;
+ pGlxPixmap->hShmPixmap = 0;
+ }
+ XUNLOCK(dpy);
+
+ /* If there's damage extension, then get handle for damage events related to this pixmap */
+ if (!pContext->damageQueryFailed)
+ {
+ pGlxPixmap->hDamage = XDamageCreate(dpy, (Pixmap)draw, XDamageReportNonEmpty);
+ /*crDebug("Create: Damage for drawable 0x%x, handle 0x%x (level=%i)",
+ (unsigned int) draw, (unsigned int) pGlxPixmap->damage, (int) XDamageReportRawRectangles);*/
+ pGlxPixmap->pDamageRegion = XCreateRegion();
+ if (!pGlxPixmap->pDamageRegion)
+ {
+ crWarning("stubInitGlxPixmap failed to create empty damage region for drawable 0x%x", (unsigned int) draw);
+ }
+
+ /*We have never seen this pixmap before, so mark it as dirty for first use*/
+ pGlxPixmap->bPixmapImageDirty = True;
+ }
+ else
+ {
+ pGlxPixmap->hDamage = 0;
+ pGlxPixmap->pDamageRegion = NULL;
+ }
+
+ /* glTexSubImage2D generates GL_INVALID_OP if texture array hasn't been defined by a call to glTexImage2D first.
+ * It's fine for small textures which would be updated in stubXshmUpdateWholeImage, but we'd never call glTexImage2D for big ones.
+ * Note that we're making empty texture by passing NULL as pixels pointer, so there's no overhead transferring data to host.*/
+ if (CR_MAX_TRANSFER_SIZE < 4*pGlxPixmap->w*pGlxPixmap->h)
+ {
+ stub.spu->dispatch_table.TexImage2D(pGlxPixmap->target, 0, pGlxPixmap->format, pGlxPixmap->w, pGlxPixmap->h, 0,
+ GL_BGRA, GL_UNSIGNED_BYTE, NULL);
+ }
+
+ crHashtableAdd(pContext->pGLXPixmapsHash, (unsigned int) draw, pGlxPixmap);
+ crHashtableDelete(stub.pGLXPixmapsHash, (unsigned int) draw, crFree);
+
+ return pGlxPixmap;
+}
+
+static void stubXshmUpdateWholeImage(Display *dpy, GLXDrawable draw, GLX_Pixmap_t *pGlxPixmap)
+{
+ /* To limit the size of transferring buffer, split bigger texture into regions
+ * which fit into connection buffer. Could be done in hgcm or packspu but implementation in this place allows to avoid
+ * unnecessary memcpy.
+ * This also workarounds guest driver failures when sending 6+mb texture buffers on linux.
+ */
+ if (CR_MAX_TRANSFER_SIZE < 4*pGlxPixmap->w*pGlxPixmap->h)
+ {
+ XRectangle rect;
+
+ rect.x = pGlxPixmap->x;
+ rect.y = pGlxPixmap->y;
+ rect.width = pGlxPixmap->w;
+ rect.height = CR_MAX_TRANSFER_SIZE/(4*pGlxPixmap->w);
+
+ /*crDebug("Texture size too big, splitting in lower sized chunks. [%i,%i,%i,%i] (%i)",
+ pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h, rect.height);*/
+
+ for (; (rect.y+rect.height)<=(pGlxPixmap->y+(int)pGlxPixmap->h); rect.y+=rect.height)
+ {
+ stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
+ }
+
+ if (rect.y!=(pGlxPixmap->y+(int)pGlxPixmap->h))
+ {
+ rect.height=pGlxPixmap->h-rect.y;
+ stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
+ }
+ }
+ else
+ {
+ CRPixelPackState unpackState;
+
+ XLOCK(dpy);
+ XCopyArea(dpy, (Pixmap)draw, pGlxPixmap->hShmPixmap, pGlxPixmap->gc,
+ pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h, 0, 0);
+ /* Have to make sure XCopyArea is processed */
+ XSync(dpy, False);
+ XUNLOCK(dpy);
+
+ stubGetUnpackState(&unpackState);
+ stubSetUnpackState(&defaultPacking);
+ stub.spu->dispatch_table.TexImage2D(pGlxPixmap->target, 0, pGlxPixmap->format, pGlxPixmap->w, pGlxPixmap->h, 0,
+ GL_BGRA, GL_UNSIGNED_BYTE, stub.xshmSI.shmaddr);
+ stubSetUnpackState(&unpackState);
+ /*crDebug("Sync texture for drawable 0x%x(dmg handle 0x%x) [%i,%i,%i,%i]",
+ (unsigned int) draw, (unsigned int)pGlxPixmap->hDamage,
+ pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h);*/
+ }
+}
+
+static void stubXshmUpdateImageRect(Display *dpy, GLXDrawable draw, GLX_Pixmap_t *pGlxPixmap, XRectangle *pRect)
+{
+ /* See comment in stubXshmUpdateWholeImage */
+ if (CR_MAX_TRANSFER_SIZE < 4*pRect->width*pRect->height)
+ {
+ XRectangle rect;
+
+ rect.x = pRect->x;
+ rect.y = pRect->y;
+ rect.width = pRect->width;
+ rect.height = CR_MAX_TRANSFER_SIZE/(4*pRect->width);
+
+ /*crDebug("Region size too big, splitting in lower sized chunks. [%i,%i,%i,%i] (%i)",
+ pRect->x, pRect->y, pRect->width, pRect->height, rect.height);*/
+
+ for (; (rect.y+rect.height)<=(pRect->y+pRect->height); rect.y+=rect.height)
+ {
+ stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
+ }
+
+ if (rect.y!=(pRect->y+pRect->height))
+ {
+ rect.height=pRect->y+pRect->height-rect.y;
+ stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
+ }
+ }
+ else
+ {
+ CRPixelPackState unpackState;
+
+ XLOCK(dpy);
+ XCopyArea(dpy, (Pixmap)draw, pGlxPixmap->hShmPixmap, pGlxPixmap->gc,
+ pRect->x, pRect->y, pRect->width, pRect->height, 0, 0);
+ /* Have to make sure XCopyArea is processed */
+ XSync(dpy, False);
+ XUNLOCK(dpy);
+
+ stubGetUnpackState(&unpackState);
+ stubSetUnpackState(&defaultPacking);
+ if (pRect->width!=pGlxPixmap->w)
+ {
+ stub.spu->dispatch_table.PixelStorei(GL_UNPACK_ROW_LENGTH, pGlxPixmap->w);
+ }
+ stub.spu->dispatch_table.TexSubImage2D(pGlxPixmap->target, 0, pRect->x, pRect->y, pRect->width, pRect->height,
+ GL_BGRA, GL_UNSIGNED_BYTE, stub.xshmSI.shmaddr);
+ stubSetUnpackState(&unpackState);
+
+ /*crDebug("Region sync texture for drawable 0x%x(dmg handle 0x%x) [%i,%i,%i,%i]",
+ (unsigned int) draw, (unsigned int)pGlxPixmap->hDamage,
+ pRect->x, pRect->y, pRect->width, pRect->height);*/
+ }
+}
+
+#if 0
+Bool checkevents(Display *display, XEvent *event, XPointer arg)
+{
+ //crDebug("got type: 0x%x", event->type);
+ if (event->type==damage_evb+XDamageNotify)
+ {
+ ContextInfo *context = stubGetCurrentContext();
+ XDamageNotifyEvent *e = (XDamageNotifyEvent *) event;
+ /* we're interested in pixmaps only...and those have e->drawable set to 0 or other strange value for some odd reason
+ * so have to walk glxpixmaps hashtable to find if we have damage event handle assigned to some pixmap
+ */
+ /*crDebug("Event: Damage for drawable 0x%x, handle 0x%x (level=%i) [%i,%i,%i,%i]",
+ (unsigned int) e->drawable, (unsigned int) e->damage, (int) e->level,
+ e->area.x, e->area.y, e->area.width, e->area.height);*/
+ CRASSERT(context);
+ crHashtableWalk(context->pGLXPixmapsHash, checkdamageCB, e);
+ }
+ return False;
+}
+#endif
+
+/** @todo check what error codes could we throw for failures here*/
+DECLEXPORT(void) VBOXGLXTAG(glXBindTexImageEXT)(Display *dpy, GLXDrawable draw, int buffer, const int *attrib_list)
+{
+ ContextInfo *context = stubGetCurrentContext();
+ GLX_Pixmap_t *pGlxPixmap;
+ RT_NOREF(buffer, attrib_list);
+
+ if (!context)
+ {
+ crWarning("glXBindTexImageEXT called without current context");
+ return;
+ }
+
+ pGlxPixmap = (GLX_Pixmap_t *) crHashtableSearch(context->pGLXPixmapsHash, (unsigned int) draw);
+ if (!pGlxPixmap)
+ {
+ pGlxPixmap = (GLX_Pixmap_t *) crHashtableSearch(stub.pGLXPixmapsHash, (unsigned int) draw);
+ if (!pGlxPixmap)
+ {
+ crDebug("Unknown drawable 0x%x in glXBindTexImageEXT!", (unsigned int) draw);
+ return;
+ }
+ pGlxPixmap = stubInitGlxPixmap(pGlxPixmap, dpy, draw, context);
+ if (!pGlxPixmap)
+ {
+ crDebug("glXBindTexImageEXT failed to get pGlxPixmap");
+ return;
+ }
+ }
+
+ /* If there's damage extension, then process incoming events as we need the information right now */
+ if (!context->damageQueryFailed)
+ {
+ /* Sync connection */
+ XLOCK(dpy);
+ XSync(dpy, False);
+ XUNLOCK(dpy);
+
+ stubFetchDamageOnDrawable(dpy, pGlxPixmap);
+ }
+
+ /* No shared memory? Rollback to use slow x protocol then */
+ if (stub.xshmSI.shmid<0)
+ {
+ /** @todo add damage support here too*/
+ XImage *pxim;
+ CRPixelPackState unpackState;
+
+ XLOCK(dpy);
+ pxim = XGetImage(dpy, (Pixmap)draw, pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h, AllPlanes, ZPixmap);
+ XUNLOCK(dpy);
+ /*if (pxim)
+ {
+ if (!ptextable)
+ {
+ ptextable = crAllocHashtable();
+ }
+ pm = crHashtableSearch(ptextable, (unsigned int) draw);
+ if (!pm)
+ {
+ pm = crCalloc(sizeof(pminfo));
+ crHashtableAdd(ptextable, (unsigned int) draw, pm);
+ }
+ pm->w = w;
+ pm->h = h;
+ if (pm->data) crFree(pm->data);
+ pm->data = crAlloc(4*w*h);
+ crMemcpy(pm->data, (void*)(&(pxim->data[0])), 4*w*h);
+ }*/
+
+ if (NULL==pxim)
+ {
+ crWarning("Failed, to get pixmap data for 0x%x", (unsigned int) draw);
+ return;
+ }
+
+ stubGetUnpackState(&unpackState);
+ stubSetUnpackState(&defaultPacking);
+ stub.spu->dispatch_table.TexImage2D(pGlxPixmap->target, 0, pGlxPixmap->format, pxim->width, pxim->height, 0,
+ GL_BGRA, GL_UNSIGNED_BYTE, (void*)(&(pxim->data[0])));
+ stubSetUnpackState(&unpackState);
+ XDestroyImage(pxim);
+ }
+ else /* Use shm to get pixmap data */
+ {
+ /* Check if we have damage extension */
+ if (!context->damageQueryFailed)
+ {
+ if (pGlxPixmap->bPixmapImageDirty)
+ {
+ /* Either we failed to allocate damage region or this pixmap is marked for full update */
+ if (!pGlxPixmap->pDamageRegion || XEmptyRegion(pGlxPixmap->pDamageRegion))
+ {
+ /*crDebug("**FULL** update for 0x%x", (unsigned int)draw);*/
+ stubXshmUpdateWholeImage(dpy, draw, pGlxPixmap);
+ }
+ else
+ {
+ long fullArea, damageArea=0, clipdamageArea, i;
+ XRectangle damageClipBox;
+
+ fullArea = pGlxPixmap->w * pGlxPixmap->h;
+ XClipBox(pGlxPixmap->pDamageRegion, &damageClipBox);
+ clipdamageArea = damageClipBox.width * damageClipBox.height;
+
+ //crDebug("FullSize [%i,%i,%i,%i]", pGlxPixmap->x, pGlxPixmap->y, pGlxPixmap->w, pGlxPixmap->h);
+ //crDebug("Clip [%i,%i,%i,%i]", damageClipBox.x, damageClipBox.y, damageClipBox.width, damageClipBox.height);
+
+ for (i=0; i<pGlxPixmap->pDamageRegion->numRects; ++i)
+ {
+ BoxPtr pBox = &pGlxPixmap->pDamageRegion->rects[i];
+ damageArea += (pBox->x2-pBox->x1)*(pBox->y2-pBox->y1);
+ //crDebug("Damage rect [%i,%i,%i,%i]", pBox->x1, pBox->y1, pBox->x2, pBox->y2);
+ }
+
+ if (damageArea>clipdamageArea || clipdamageArea>fullArea)
+ {
+ crWarning("glXBindTexImageEXT, damage regions seems to be broken, forcing full update");
+ /*crDebug("**FULL** update for 0x%x, numRect=%li, *FS*=%li, CS=%li, DS=%li",
+ (unsigned int)draw, pGlxPixmap->pDamageRegion->numRects, fullArea, clipdamageArea, damageArea);*/
+ stubXshmUpdateWholeImage(dpy, draw, pGlxPixmap);
+ }
+ else /*We have corect damage info*/
+ {
+ if (CR_MIN_DAMAGE_PROFIT_SIZE > (fullArea-damageArea))
+ {
+ /*crDebug("**FULL** update for 0x%x, numRect=%li, *FS*=%li, CS=%li, DS=%li",
+ (unsigned int)draw, pGlxPixmap->pDamageRegion->numRects, fullArea, clipdamageArea, damageArea);*/
+ stubXshmUpdateWholeImage(dpy, draw, pGlxPixmap);
+ }
+ else if (CR_MIN_DAMAGE_PROFIT_SIZE > (clipdamageArea-damageArea))
+ {
+ /*crDebug("**PARTIAL** update for 0x%x, numRect=%li, FS=%li, *CS*=%li, DS=%li",
+ (unsigned int)draw, pGlxPixmap->pDamageRegion->numRects, fullArea, clipdamageArea, damageArea);*/
+ stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &damageClipBox);
+ }
+ else
+ {
+ /*crDebug("**PARTIAL** update for 0x%x, numRect=*%li*, FS=%li, CS=%li, *DS*=%li",
+ (unsigned int)draw, pGlxPixmap->pDamageRegion->numRects, fullArea, clipdamageArea, damageArea);*/
+ for (i=0; i<pGlxPixmap->pDamageRegion->numRects; ++i)
+ {
+ XRectangle rect;
+ BoxPtr pBox = &pGlxPixmap->pDamageRegion->rects[i];
+
+ rect.x = pBox->x1;
+ rect.y = pBox->y1;
+ rect.width = pBox->x2-pBox->x1;
+ rect.height = pBox->y2-pBox->y1;
+
+ stubXshmUpdateImageRect(dpy, draw, pGlxPixmap, &rect);
+ }
+ }
+ }
+ }
+
+ /* Clean dirty flag and damage region */
+ pGlxPixmap->bPixmapImageDirty = False;
+ if (pGlxPixmap->pDamageRegion)
+ EMPTY_REGION(pGlxPixmap->pDamageRegion);
+ }
+ }
+ else
+ {
+ stubXshmUpdateWholeImage(dpy, draw, pGlxPixmap);
+ }
+ }
+}
+
+DECLEXPORT(void) VBOXGLXTAG(glXReleaseTexImageEXT)(Display *dpy, GLXDrawable draw, int buffer)
+{
+ (void) dpy;
+ (void) draw;
+ (void) buffer;
+ //crDebug("glXReleaseTexImageEXT 0x%x", (unsigned int)draw);
+}
+#endif
+
+#endif /* GLX_EXTRAS */
+
+
+#ifdef GLX_SGIX_video_resize
+/* more dummy funcs. These help when linking with older GLUTs */
+
+DECLEXPORT(int) VBOXGLXTAG(glXBindChannelToWindowSGIX)(Display *dpy, int scrn, int chan, Window w)
+{
+ (void) dpy;
+ (void) scrn;
+ (void) chan;
+ (void) w;
+ crDebug("glXBindChannelToWindowSGIX");
+ return 0;
+}
+
+DECLEXPORT(int) VBOXGLXTAG(glXChannelRectSGIX)(Display *dpy, int scrn, int chan, int x , int y, int w, int h)
+{
+ (void) dpy;
+ (void) scrn;
+ (void) chan;
+ (void) x;
+ (void) y;
+ (void) w;
+ (void) h;
+ crDebug("glXChannelRectSGIX");
+ return 0;
+}
+
+DECLEXPORT(int) VBOXGLXTAG(glXQueryChannelRectSGIX)(Display *dpy, int scrn, int chan, int *x, int *y, int *w, int *h)
+{
+ (void) dpy;
+ (void) scrn;
+ (void) chan;
+ (void) x;
+ (void) y;
+ (void) w;
+ (void) h;
+ crDebug("glXQueryChannelRectSGIX");
+ return 0;
+}
+
+DECLEXPORT(int) VBOXGLXTAG(glXQueryChannelDeltasSGIX)(Display *dpy, int scrn, int chan, int *dx, int *dy, int *dw, int *dh)
+{
+ (void) dpy;
+ (void) scrn;
+ (void) chan;
+ (void) dx;
+ (void) dy;
+ (void) dw;
+ (void) dh;
+ crDebug("glXQueryChannelDeltasSGIX");
+ return 0;
+}
+
+DECLEXPORT(int) VBOXGLXTAG(glXChannelRectSyncSGIX)(Display *dpy, int scrn, int chan, GLenum synctype)
+{
+ (void) dpy;
+ (void) scrn;
+ (void) chan;
+ (void) synctype;
+ crDebug("glXChannelRectSyncSGIX");
+ return 0;
+}
+
+#endif /* GLX_SGIX_video_resize */
+
+#ifdef VBOXOGL_FAKEDRI
+DECLEXPORT(const char *) VBOXGLXTAG(glXGetDriverConfig)(const char *driverName)
+{
+ return NULL;
+}
+
+DECLEXPORT(void) VBOXGLXTAG(glXFreeMemoryMESA)(Display *dpy, int scrn, void *pointer)
+{
+ (void) dpy;
+ (void) scrn;
+ (void) pointer;
+}
+
+DECLEXPORT(GLXContext) VBOXGLXTAG(glXImportContextEXT)(Display *dpy, GLXContextID contextID)
+{
+ (void) dpy;
+ (void) contextID;
+ return NULL;
+}
+
+DECLEXPORT(GLXContextID) VBOXGLXTAG(glXGetContextIDEXT)(const GLXContext ctx)
+{
+ (void) ctx;
+ return 0;
+}
+
+DECLEXPORT(Bool) VBOXGLXTAG(glXMakeCurrentReadSGI)(Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
+{
+ return VBOXGLXTAG(glXMakeContextCurrent)(display, draw, read, ctx);
+}
+
+DECLEXPORT(const char *) VBOXGLXTAG(glXGetScreenDriver)(Display *dpy, int scrNum)
+{
+ static char *screendriver = "vboxvideo";
+ return screendriver;
+}
+
+DECLEXPORT(Display *) VBOXGLXTAG(glXGetCurrentDisplayEXT)(void)
+{
+ return VBOXGLXTAG(glXGetCurrentDisplay());
+}
+
+DECLEXPORT(void) VBOXGLXTAG(glXFreeContextEXT)(Display *dpy, GLXContext ctx)
+{
+ VBOXGLXTAG(glXDestroyContext(dpy, ctx));
+}
+
+/*Mesa internal*/
+DECLEXPORT(int) VBOXGLXTAG(glXQueryContextInfoEXT)(Display *dpy, GLXContext ctx)
+{
+ (void) dpy;
+ (void) ctx;
+ return 0;
+}
+
+DECLEXPORT(void *) VBOXGLXTAG(glXAllocateMemoryMESA)(Display *dpy, int scrn,
+ size_t size, float readFreq,
+ float writeFreq, float priority)
+{
+ (void) dpy;
+ (void) scrn;
+ (void) size;
+ (void) readFreq;
+ (void) writeFreq;
+ (void) priority;
+ return NULL;
+}
+
+DECLEXPORT(GLuint) VBOXGLXTAG(glXGetMemoryOffsetMESA)(Display *dpy, int scrn, const void *pointer)
+{
+ (void) dpy;
+ (void) scrn;
+ (void) pointer;
+ return 0;
+}
+
+DECLEXPORT(GLXPixmap) VBOXGLXTAG(glXCreateGLXPixmapMESA)(Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap)
+{
+ (void) dpy;
+ (void) visual;
+ (void) pixmap;
+ (void) cmap;
+ return 0;
+}
+
+#endif /*VBOXOGL_FAKEDRI*/
diff --git a/src/VBox/Additions/common/crOpenGL/glx_c_exports.c b/src/VBox/Additions/common/crOpenGL/glx_c_exports.c
new file mode 100644
index 00000000..c8068375
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/glx_c_exports.c
@@ -0,0 +1,375 @@
+/* $Id: glx_c_exports.c $ */
+/** @file
+ * VirtualBox guest OpenGL DRI GLX C stubs
+ */
+
+/*
+ * Copyright (C) 2006-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include "stub.h"
+#include "dri_glx.h"
+#include "fakedri_drv.h"
+
+
+#ifdef VBOXOGL_FAKEDRI
+/*DECLEXPORT(void) VBOXGLXENTRYTAG(glXGetDriverConfig)(const char *driverName)
+{
+ return glxim.GetDriverConfig(driverName);
+}*/
+
+DECLEXPORT(void) VBOXGLXENTRYTAG(glXFreeMemoryMESA)(Display *dpy, int scrn, void *pointer)
+{
+ return glxim.FreeMemoryMESA(dpy, scrn, pointer);
+}
+
+DECLEXPORT(GLXContext) VBOXGLXENTRYTAG(glXImportContextEXT)(Display *dpy, GLXContextID contextID)
+{
+ return glxim.ImportContextEXT(dpy, contextID);
+}
+
+DECLEXPORT(GLXContextID) VBOXGLXENTRYTAG(glXGetContextIDEXT)(const GLXContext ctx)
+{
+ return glxim.GetContextIDEXT(ctx);
+}
+
+DECLEXPORT(Bool) VBOXGLXENTRYTAG(glXMakeCurrentReadSGI)(Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
+{
+ return glxim.MakeCurrentReadSGI(display, draw, read, ctx);
+}
+
+
+/*const char * VBOXGLXENTRYTAG(glXGetScreenDriver)(Display *dpy, int scrNum)
+{
+ return glxim.GetScreenDriver(dpy, scrNum);
+}*/
+
+
+DECLEXPORT(Display*) VBOXGLXENTRYTAG(glXGetCurrentDisplayEXT)(void)
+{
+ return glxim.GetCurrentDisplayEXT();
+}
+
+DECLEXPORT(void) VBOXGLXENTRYTAG(glXFreeContextEXT)(Display *dpy, GLXContext ctx)
+{
+ return glxim.FreeContextEXT(dpy, ctx);
+}
+
+/*Mesa internal*/
+DECLEXPORT(int) VBOXGLXENTRYTAG(glXQueryContextInfoEXT)(Display *dpy, GLXContext ctx)
+{
+ return glxim.QueryContextInfoEXT(dpy, ctx);
+}
+
+DECLEXPORT(void *) VBOXGLXENTRYTAG(glXAllocateMemoryMESA)(Display *dpy, int scrn,
+ size_t size, float readFreq,
+ float writeFreq, float priority)
+{
+ return glxim.AllocateMemoryMESA(dpy, scrn, size, readFreq, writeFreq, priority);
+}
+
+DECLEXPORT(GLuint) VBOXGLXENTRYTAG(glXGetMemoryOffsetMESA)(Display *dpy, int scrn, const void *pointer )
+{
+ return glxim.GetMemoryOffsetMESA(dpy, scrn, pointer);
+}
+
+
+DECLEXPORT(GLXPixmap) VBOXGLXENTRYTAG(glXCreateGLXPixmapMESA)(Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap)
+{
+ return glxim.CreateGLXPixmapMESA(dpy, visual, pixmap, cmap);
+}
+#endif
+
+/*Common glX functions*/
+DECLEXPORT(void) VBOXGLXENTRYTAG(glXCopyContext)( Display *dpy, GLXContext src, GLXContext dst, unsigned long mask)
+{
+ return glxim.CopyContext(dpy, src, dst, mask);
+}
+
+
+DECLEXPORT(void) VBOXGLXENTRYTAG(glXUseXFont)(Font font, int first, int count, int listBase)
+{
+ return glxim.UseXFont(font, first, count, listBase);
+}
+
+DECLEXPORT(CR_GLXFuncPtr) VBOXGLXENTRYTAG(glXGetProcAddress)(const GLubyte *name)
+{
+ return glxim.GetProcAddress(name);
+}
+
+DECLEXPORT(Bool) VBOXGLXENTRYTAG(glXQueryExtension)(Display *dpy, int *errorBase, int *eventBase)
+{
+ return glxim.QueryExtension(dpy, errorBase, eventBase);
+}
+
+DECLEXPORT(Bool) VBOXGLXENTRYTAG(glXIsDirect)(Display *dpy, GLXContext ctx)
+{
+ return glxim.IsDirect(dpy, ctx);
+}
+
+DECLEXPORT(GLXPixmap) VBOXGLXENTRYTAG(glXCreateGLXPixmap)(Display *dpy, XVisualInfo *vis, Pixmap pixmap)
+{
+ return glxim.CreateGLXPixmap(dpy, vis, pixmap);
+}
+
+DECLEXPORT(void) VBOXGLXENTRYTAG(glXSwapBuffers)(Display *dpy, GLXDrawable drawable)
+{
+ return glxim.SwapBuffers(dpy, drawable);
+}
+
+
+DECLEXPORT(GLXDrawable) VBOXGLXENTRYTAG(glXGetCurrentDrawable)(void)
+{
+ return glxim.GetCurrentDrawable();
+}
+
+DECLEXPORT(void) VBOXGLXENTRYTAG(glXWaitGL)(void)
+{
+ return glxim.WaitGL();
+}
+
+DECLEXPORT(Display *) VBOXGLXENTRYTAG(glXGetCurrentDisplay)(void)
+{
+ return glxim.GetCurrentDisplay();
+}
+
+DECLEXPORT(const char *) VBOXGLXENTRYTAG(glXQueryServerString)(Display *dpy, int screen, int name)
+{
+ return glxim.QueryServerString(dpy, screen, name);
+}
+
+DECLEXPORT(GLXContext) VBOXGLXENTRYTAG(glXCreateContext)(Display *dpy, XVisualInfo *vis, GLXContext share, Bool direct)
+{
+ return glxim.CreateContext(dpy, vis, share, direct);
+}
+
+DECLEXPORT(int) VBOXGLXENTRYTAG(glXGetConfig)(Display *dpy, XVisualInfo *vis, int attrib, int *value)
+{
+ return glxim.GetConfig(dpy, vis, attrib, value);
+}
+
+DECLEXPORT(void) VBOXGLXENTRYTAG(glXWaitX)(void)
+{
+ return glxim.WaitX();
+}
+
+DECLEXPORT(GLXContext) VBOXGLXENTRYTAG(glXGetCurrentContext)(void)
+{
+ return glxim.GetCurrentContext();
+}
+
+DECLEXPORT(const char *) VBOXGLXENTRYTAG(glXGetClientString)(Display *dpy, int name)
+{
+ return glxim.GetClientString(dpy, name);
+}
+
+DECLEXPORT(Bool) VBOXGLXENTRYTAG(glXMakeCurrent)(Display *dpy, GLXDrawable drawable, GLXContext ctx)
+{
+ return glxim.MakeCurrent(dpy, drawable, ctx);
+}
+
+DECLEXPORT(void) VBOXGLXENTRYTAG(glXDestroyContext)(Display *dpy, GLXContext ctx)
+{
+ return glxim.DestroyContext(dpy, ctx);
+}
+
+DECLEXPORT(CR_GLXFuncPtr) VBOXGLXENTRYTAG(glXGetProcAddressARB)(const GLubyte *name)
+{
+ return glxim.GetProcAddressARB(name);
+}
+
+DECLEXPORT(void) VBOXGLXENTRYTAG(glXDestroyGLXPixmap)(Display *dpy, GLXPixmap pix)
+{
+ return glxim.DestroyGLXPixmap(dpy, pix);
+}
+
+DECLEXPORT(Bool) VBOXGLXENTRYTAG(glXQueryVersion)(Display *dpy, int *major, int *minor)
+{
+ return glxim.QueryVersion(dpy, major, minor);
+}
+
+DECLEXPORT(XVisualInfo *) VBOXGLXENTRYTAG(glXChooseVisual)(Display *dpy, int screen, int *attribList)
+{
+ return glxim.ChooseVisual(dpy, screen, attribList);
+}
+
+DECLEXPORT(const char *) VBOXGLXENTRYTAG(glXQueryExtensionsString)(Display *dpy, int screen)
+{
+ return glxim.QueryExtensionsString(dpy, screen);
+}
+
+#if GLX_EXTRAS
+DECLEXPORT(GLXPbufferSGIX) VBOXGLXENTRYTAG(glXCreateGLXPbufferSGIX)
+(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list)
+{
+ return glxim.CreateGLXPbufferSGIX(dpy, config, width, height, attrib_list);
+}
+
+DECLEXPORT(int) VBOXGLXENTRYTAG(glXQueryGLXPbufferSGIX)
+(Display *dpy, GLXPbuffer pbuf, int attribute, unsigned int *value)
+{
+ return glxim.QueryGLXPbufferSGIX(dpy, pbuf, attribute, value);
+}
+
+DECLEXPORT(GLXFBConfigSGIX *) VBOXGLXENTRYTAG(glXChooseFBConfigSGIX)
+(Display *dpy, int screen, int *attrib_list, int *nelements)
+{
+ return glxim.ChooseFBConfigSGIX(dpy, screen, attrib_list, nelements);
+}
+
+DECLEXPORT(void) VBOXGLXENTRYTAG(glXDestroyGLXPbufferSGIX)(Display *dpy, GLXPbuffer pbuf)
+{
+ return glxim.DestroyGLXPbufferSGIX(dpy, pbuf);
+}
+
+DECLEXPORT(void) VBOXGLXENTRYTAG(glXSelectEventSGIX)(Display *dpy, GLXDrawable drawable, unsigned long mask)
+{
+ return glxim.SelectEventSGIX(dpy, drawable, mask);
+}
+
+DECLEXPORT(void) VBOXGLXENTRYTAG(glXGetSelectedEventSGIX)(Display *dpy, GLXDrawable drawable, unsigned long *mask)
+{
+ return glxim.GetSelectedEventSGIX(dpy, drawable, mask);
+}
+
+DECLEXPORT(GLXFBConfigSGIX) VBOXGLXENTRYTAG(glXGetFBConfigFromVisualSGIX)(Display *dpy, XVisualInfo *vis)
+{
+ return glxim.GetFBConfigFromVisualSGIX(dpy, vis);
+}
+
+DECLEXPORT(XVisualInfo *) VBOXGLXENTRYTAG(glXGetVisualFromFBConfigSGIX)(Display *dpy, GLXFBConfig config)
+{
+ return glxim.GetVisualFromFBConfigSGIX(dpy, config);
+}
+
+DECLEXPORT(GLXContext) VBOXGLXENTRYTAG(glXCreateContextWithConfigSGIX)
+(Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct)
+{
+ return glxim.CreateContextWithConfigSGIX(dpy, config, render_type, share_list, direct);
+}
+
+DECLEXPORT(GLXPixmap) VBOXGLXENTRYTAG(glXCreateGLXPixmapWithConfigSGIX)(Display *dpy, GLXFBConfig config, Pixmap pixmap)
+{
+ return glxim.CreateGLXPixmapWithConfigSGIX(dpy, config, pixmap);
+}
+
+DECLEXPORT(int) VBOXGLXENTRYTAG(glXGetFBConfigAttribSGIX)(Display *dpy, GLXFBConfig config, int attribute, int *value)
+{
+ return glxim.GetFBConfigAttribSGIX(dpy, config, attribute, value);
+}
+
+
+/*
+ * GLX 1.3 functions
+ */
+DECLEXPORT(GLXFBConfig *) VBOXGLXENTRYTAG(glXChooseFBConfig)(Display *dpy, int screen, ATTRIB_TYPE *attrib_list, int *nelements)
+{
+ return glxim.ChooseFBConfig(dpy, screen, attrib_list, nelements);
+}
+
+DECLEXPORT(GLXPbuffer) VBOXGLXENTRYTAG(glXCreatePbuffer)(Display *dpy, GLXFBConfig config, ATTRIB_TYPE *attrib_list)
+{
+ return glxim.CreatePbuffer(dpy, config, attrib_list);
+}
+
+DECLEXPORT(GLXPixmap) VBOXGLXENTRYTAG(glXCreatePixmap)(Display *dpy, GLXFBConfig config, Pixmap pixmap, const ATTRIB_TYPE *attrib_list)
+{
+ return glxim.CreatePixmap(dpy, config, pixmap, attrib_list);
+}
+
+DECLEXPORT(GLXWindow) VBOXGLXENTRYTAG(glXCreateWindow)(Display *dpy, GLXFBConfig config, Window win, ATTRIB_TYPE *attrib_list)
+{
+ return glxim.CreateWindow(dpy, config, win, attrib_list);
+}
+
+
+DECLEXPORT(GLXContext) VBOXGLXENTRYTAG(glXCreateNewContext)
+(Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct)
+{
+ return glxim.CreateNewContext(dpy, config, render_type, share_list, direct);
+}
+
+DECLEXPORT(void) VBOXGLXENTRYTAG(glXDestroyPbuffer)(Display *dpy, GLXPbuffer pbuf)
+{
+ return glxim.DestroyPbuffer(dpy, pbuf);
+}
+
+DECLEXPORT(void) VBOXGLXENTRYTAG(glXDestroyPixmap)(Display *dpy, GLXPixmap pixmap)
+{
+ return glxim.DestroyPixmap(dpy, pixmap);
+}
+
+DECLEXPORT(void) VBOXGLXENTRYTAG(glXDestroyWindow)(Display *dpy, GLXWindow win)
+{
+ return glxim.DestroyWindow(dpy, win);
+}
+
+DECLEXPORT(GLXDrawable) VBOXGLXENTRYTAG(glXGetCurrentReadDrawable)(void)
+{
+ return glxim.GetCurrentReadDrawable();
+}
+
+DECLEXPORT(int) VBOXGLXENTRYTAG(glXGetFBConfigAttrib)(Display *dpy, GLXFBConfig config, int attribute, int *value)
+{
+ return glxim.GetFBConfigAttrib(dpy, config, attribute, value);
+}
+
+DECLEXPORT(GLXFBConfig *) VBOXGLXENTRYTAG(glXGetFBConfigs)(Display *dpy, int screen, int *nelements)
+{
+ return glxim.GetFBConfigs(dpy, screen, nelements);
+}
+
+DECLEXPORT(void) VBOXGLXENTRYTAG(glXGetSelectedEvent)(Display *dpy, GLXDrawable draw, unsigned long *event_mask)
+{
+ return glxim.GetSelectedEvent(dpy, draw, event_mask);
+}
+
+DECLEXPORT(XVisualInfo *) VBOXGLXENTRYTAG(glXGetVisualFromFBConfig)(Display *dpy, GLXFBConfig config)
+{
+ return glxim.GetVisualFromFBConfig(dpy, config);
+}
+
+DECLEXPORT(Bool) VBOXGLXENTRYTAG(glXMakeContextCurrent)(Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
+{
+ return glxim.MakeContextCurrent(display, draw, read, ctx);
+}
+
+DECLEXPORT(int) VBOXGLXENTRYTAG(glXQueryContext)(Display *dpy, GLXContext ctx, int attribute, int *value)
+{
+ return glxim.QueryContext(dpy, ctx, attribute, value);
+}
+
+DECLEXPORT(void) VBOXGLXENTRYTAG(glXQueryDrawable)(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value)
+{
+ return glxim.QueryDrawable(dpy, draw, attribute, value);
+}
+
+DECLEXPORT(void) VBOXGLXENTRYTAG(glXSelectEvent)(Display *dpy, GLXDrawable draw, unsigned long event_mask)
+{
+ return glxim.SelectEvent(dpy, draw, event_mask);
+}
+
+/*
+#ifdef CR_EXT_texture_from_pixmap
+DECLEXPORT(void) VBOXGLXENTRYTAG(glXBindTexImageEXT)(Display *dpy, GLXDrawable draw, int buffer, const int *attrib_list)
+{
+ return glxim.BindTexImageEXT(dpy, draw, buffer, attrib_list);
+}
+
+DECLEXPORT(void) VBOXGLXENTRYTAG(glXReleaseTexImageEXT)(Display *dpy, GLXDrawable draw, int buffer)
+{
+ return glxim.ReleaseTexImageEXT(dpy, draw, buffer);
+}
+#endif
+*/
+
+#endif /* GLX_EXTRAS */
+
diff --git a/src/VBox/Additions/common/crOpenGL/glx_proto.h b/src/VBox/Additions/common/crOpenGL/glx_proto.h
new file mode 100644
index 00000000..ee35dce1
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/glx_proto.h
@@ -0,0 +1,149 @@
+/* $Id: glx_proto.h $ */
+/** @file
+ * VirtualBox guest OpenGL DRI GLX header C prototypes
+ */
+
+/*
+ * Copyright (C) 2006-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef GA_INCLUDED_SRC_common_crOpenGL_glx_proto_h
+#define GA_INCLUDED_SRC_common_crOpenGL_glx_proto_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "chromium.h"
+#include "stub.h"
+
+#if defined(VBOXOGL_FAKEDRI) || defined(VBOXOGL_DRI)
+typedef const char * (*PGLXFUNC_GetDriverConfig)(const char *driverName);
+typedef void (*PGLXFUNC_FreeMemoryMESA)(Display *dpy, int scrn, void *pointer);
+typedef GLXContext (*PGLXFUNC_ImportContextEXT)(Display *dpy, GLXContextID contextID);
+typedef GLXContextID (*PGLXFUNC_GetContextIDEXT)(const GLXContext ctx);
+typedef Bool (*PGLXFUNC_MakeCurrentReadSGI)(Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
+typedef const char * (*PGLXFUNC_GetScreenDriver)(Display *dpy, int scrNum);
+typedef Display * (*PGLXFUNC_GetCurrentDisplayEXT)(void);
+typedef void (*PGLXFUNC_FreeContextEXT)(Display *dpy, GLXContext ctx);
+
+/*Mesa internal*/
+typedef int (*PGLXFUNC_QueryContextInfoEXT)(Display *dpy, GLXContext ctx);
+typedef void * (*PGLXFUNC_AllocateMemoryMESA)(Display *dpy, int scrn,
+ size_t size, float readFreq,
+ float writeFreq, float priority);
+typedef GLuint (*PGLXFUNC_GetMemoryOffsetMESA)(Display *dpy, int scrn, const void *pointer );
+typedef GLXPixmap (*PGLXFUNC_CreateGLXPixmapMESA)(Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap);
+#endif
+
+/*Common glX functions*/
+typedef void (*PGLXFUNC_CopyContext)(Display *dpy, GLXContext src, GLXContext dst,unsigned long mask);
+typedef void (*PGLXFUNC_UseXFont)(Font font, int first, int count, int listBase);
+typedef CR_GLXFuncPtr (*PGLXFUNC_GetProcAddress)(const GLubyte *name);
+typedef Bool (*PGLXFUNC_QueryExtension)(Display *dpy, int *errorBase, int *eventBase);
+typedef Bool (*PGLXFUNC_IsDirect)(Display *dpy, GLXContext ctx);
+typedef GLXPixmap (*PGLXFUNC_CreateGLXPixmap)(Display *dpy, XVisualInfo *vis, Pixmap pixmap);
+typedef void (*PGLXFUNC_SwapBuffers)(Display *dpy, GLXDrawable drawable);
+typedef GLXDrawable (*PGLXFUNC_GetCurrentDrawable)(void);
+typedef void (*PGLXFUNC_WaitGL)(void);
+typedef Display * (*PGLXFUNC_GetCurrentDisplay)(void);
+typedef const char * (*PGLXFUNC_QueryServerString)(Display *dpy, int screen, int name);
+typedef GLXContext (*PGLXFUNC_CreateContext)(Display *dpy, XVisualInfo *vis, GLXContext share, Bool direct);
+typedef int (*PGLXFUNC_GetConfig)(Display *dpy, XVisualInfo *vis, int attrib, int *value);
+typedef void (*PGLXFUNC_WaitX)(void);
+typedef GLXContext (*PGLXFUNC_GetCurrentContext)(void);
+typedef const char * (*PGLXFUNC_GetClientString)(Display *dpy, int name);
+typedef Bool (*PGLXFUNC_MakeCurrent)(Display *dpy, GLXDrawable drawable, GLXContext ctx);
+typedef void (*PGLXFUNC_DestroyContext)(Display *dpy, GLXContext ctx);
+typedef CR_GLXFuncPtr (*PGLXFUNC_GetProcAddressARB)(const GLubyte *name);
+typedef void (*PGLXFUNC_DestroyGLXPixmap)(Display *dpy, GLXPixmap pix);
+typedef Bool (*PGLXFUNC_QueryVersion)(Display *dpy, int *major, int *minor);
+typedef XVisualInfo * (*PGLXFUNC_ChooseVisual)(Display *dpy, int screen, int *attribList);
+typedef const char * (*PGLXFUNC_QueryExtensionsString)(Display *dpy, int screen);
+
+/**
+ * Set this to 1 if you want to build stub functions for the
+ * GL_SGIX_pbuffer and GLX_SGIX_fbconfig extensions.
+ * This used to be disabled, due to "messy compilation issues",
+ * according to the earlier comment; but they're needed just
+ * to resolve symbols for OpenInventor applications, and I
+ * haven't found any reference to exactly what the "messy compilation
+ * issues" are, so I'm re-enabling the code by default.
+ */
+#define GLX_EXTRAS 1
+
+#define GLX_SGIX_video_resize 1
+
+/**
+ * Prototypes, in case they're not in glx.h or glxext.h
+ * Unfortunately, there's some inconsistency between the extension
+ * specs, and the SGI, NVIDIA, XFree86 and common glxext.h header
+ * files.
+ */
+#if defined(GLX_GLXEXT_VERSION)
+/* match glxext.h, XFree86, Mesa */
+#define ATTRIB_TYPE const int
+#else
+#define ATTRIB_TYPE int
+#endif
+
+#if GLX_EXTRAS
+typedef GLXPbufferSGIX (*PGLXFUNC_CreateGLXPbufferSGIX)
+(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list);
+
+typedef int (*PGLXFUNC_QueryGLXPbufferSGIX)
+(Display *dpy, GLXPbuffer pbuf, int attribute, unsigned int *value);
+
+typedef GLXFBConfigSGIX * (*PGLXFUNC_ChooseFBConfigSGIX)
+(Display *dpy, int screen, int *attrib_list, int *nelements);
+
+typedef void (*PGLXFUNC_DestroyGLXPbufferSGIX)(Display *dpy, GLXPbuffer pbuf);
+typedef void (*PGLXFUNC_SelectEventSGIX)(Display *dpy, GLXDrawable drawable, unsigned long mask);
+typedef void (*PGLXFUNC_GetSelectedEventSGIX)(Display *dpy, GLXDrawable drawable, unsigned long *mask);
+
+typedef GLXFBConfigSGIX (*PGLXFUNC_GetFBConfigFromVisualSGIX)(Display *dpy, XVisualInfo *vis);
+typedef XVisualInfo * (*PGLXFUNC_GetVisualFromFBConfigSGIX)(Display *dpy, GLXFBConfig config);
+typedef GLXContext (*PGLXFUNC_CreateContextWithConfigSGIX)
+(Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
+
+typedef GLXPixmap (*PGLXFUNC_CreateGLXPixmapWithConfigSGIX)(Display *dpy, GLXFBConfig config, Pixmap pixmap);
+typedef int (*PGLXFUNC_GetFBConfigAttribSGIX)(Display *dpy, GLXFBConfig config, int attribute, int *value);
+
+/*
+ * GLX 1.3 functions
+ */
+typedef GLXFBConfig * (*PGLXFUNC_ChooseFBConfig)(Display *dpy, int screen, ATTRIB_TYPE *attrib_list, int *nelements);
+typedef GLXPbuffer (*PGLXFUNC_CreatePbuffer)(Display *dpy, GLXFBConfig config, ATTRIB_TYPE *attrib_list);
+typedef GLXPixmap (*PGLXFUNC_CreatePixmap)(Display *dpy, GLXFBConfig config, Pixmap pixmap, const ATTRIB_TYPE *attrib_list);
+typedef GLXWindow (*PGLXFUNC_CreateWindow)(Display *dpy, GLXFBConfig config, Window win, ATTRIB_TYPE *attrib_list);
+typedef GLXContext (*PGLXFUNC_CreateNewContext)
+(Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct);
+
+typedef void (*PGLXFUNC_DestroyPbuffer)(Display *dpy, GLXPbuffer pbuf);
+typedef void (*PGLXFUNC_DestroyPixmap)(Display *dpy, GLXPixmap pixmap);
+typedef void (*PGLXFUNC_DestroyWindow)(Display *dpy, GLXWindow win);
+typedef GLXDrawable (*PGLXFUNC_GetCurrentReadDrawable)(void);
+typedef int (*PGLXFUNC_GetFBConfigAttrib)(Display *dpy, GLXFBConfig config, int attribute, int *value);
+typedef GLXFBConfig * (*PGLXFUNC_GetFBConfigs)(Display *dpy, int screen, int *nelements);
+typedef void (*PGLXFUNC_GetSelectedEvent)(Display *dpy, GLXDrawable draw, unsigned long *event_mask);
+typedef XVisualInfo * (*PGLXFUNC_GetVisualFromFBConfig)(Display *dpy, GLXFBConfig config);
+typedef Bool (*PGLXFUNC_MakeContextCurrent)(Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
+typedef int (*PGLXFUNC_QueryContext)(Display *dpy, GLXContext ctx, int attribute, int *value);
+typedef void (*PGLXFUNC_QueryDrawable)(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value);
+typedef void (*PGLXFUNC_SelectEvent)(Display *dpy, GLXDrawable draw, unsigned long event_mask);
+
+#ifdef CR_EXT_texture_from_pixmap
+typedef void (*PGLXFUNC_BindTexImageEXT)(Display *dpy, GLXDrawable draw, int buffer, const int *attrib_list);
+typedef void (*PGLXFUNC_ReleaseTexImageEXT)(Display *dpy, GLXDrawable draw, int buffer);
+#endif
+
+#endif /* GLX_EXTRAS */
+
+#endif /* !GA_INCLUDED_SRC_common_crOpenGL_glx_proto_h */
diff --git a/src/VBox/Additions/common/crOpenGL/icd_drv.c b/src/VBox/Additions/common/crOpenGL/icd_drv.c
new file mode 100644
index 00000000..3c54bb2f
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/icd_drv.c
@@ -0,0 +1,398 @@
+/* $Id: icd_drv.c $ */
+/** @file
+ * VBox OpenGL windows ICD driver functions
+ */
+
+/*
+ * Copyright (C) 2006-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include "cr_error.h"
+#include "icd_drv.h"
+#include "cr_gl.h"
+#include "stub.h"
+#include "cr_mem.h"
+
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+# include <VBoxCrHgsmi.h>
+# include <VBoxUhgsmi.h>
+#endif
+
+#include <iprt/win/windows.h>
+
+/// @todo consider
+/* We can modify chronium dispatch table functions order to match the one required by ICD,
+ * but it'd render us incompatible with other chromium SPUs and require more changes.
+ * In current state, we can use unmodified binary chromium SPUs. Question is do we need it?
+*/
+
+#define GL_FUNC(func) cr_gl##func
+
+static ICDTABLE icdTable = { 336, {
+#define ICD_ENTRY(func) (PROC)GL_FUNC(func),
+#include "VBoxICDList.h"
+#undef ICD_ENTRY
+} };
+
+/* Currently host part will misbehave re-creating context with proper visual bits
+ * if contexts with alternative visual bits is requested.
+ * For now we just report a superset of all visual bits to avoid that.
+ * Better to it on the host side as well?
+ * We could also implement properly multiple pixel formats,
+ * which should be done by implementing offscreen rendering or multiple host contexts.
+ * */
+#define VBOX_CROGL_USE_VBITS_SUPERSET
+
+#ifdef VBOX_CROGL_USE_VBITS_SUPERSET
+static GLuint desiredVisual = CR_RGB_BIT | CR_ALPHA_BIT | CR_DEPTH_BIT | CR_STENCIL_BIT | CR_ACCUM_BIT | CR_DOUBLE_BIT;
+#else
+static GLuint desiredVisual = CR_RGB_BIT;
+#endif
+
+#ifndef VBOX_CROGL_USE_VBITS_SUPERSET
+/**
+ * Compute a mask of CR_*_BIT flags which reflects the attributes of
+ * the pixel format of the given hdc.
+ */
+static GLuint ComputeVisBits( HDC hdc )
+{
+ PIXELFORMATDESCRIPTOR pfd;
+ int iPixelFormat;
+ GLuint b = 0;
+
+ iPixelFormat = GetPixelFormat( hdc );
+
+ DescribePixelFormat( hdc, iPixelFormat, sizeof(pfd), &pfd );
+
+ if (pfd.cDepthBits > 0)
+ b |= CR_DEPTH_BIT;
+ if (pfd.cAccumBits > 0)
+ b |= CR_ACCUM_BIT;
+ if (pfd.cColorBits > 8)
+ b |= CR_RGB_BIT;
+ if (pfd.cStencilBits > 0)
+ b |= CR_STENCIL_BIT;
+ if (pfd.cAlphaBits > 0)
+ b |= CR_ALPHA_BIT;
+ if (pfd.dwFlags & PFD_DOUBLEBUFFER)
+ b |= CR_DOUBLE_BIT;
+ if (pfd.dwFlags & PFD_STEREO)
+ b |= CR_STEREO_BIT;
+
+ return b;
+}
+#endif
+
+void APIENTRY DrvReleaseContext(HGLRC hglrc)
+{
+ CR_DDI_PROLOGUE();
+ /*crDebug( "DrvReleaseContext(0x%x) called", hglrc );*/
+ stubMakeCurrent( NULL, NULL );
+}
+
+BOOL APIENTRY DrvValidateVersion(DWORD version)
+{
+ CR_DDI_PROLOGUE();
+ if (stubInit()) {
+ crDebug("DrvValidateVersion %x -> TRUE\n", version);
+ return TRUE;
+ }
+
+ crDebug("DrvValidateVersion %x -> FALSE, going to use system default opengl32.dll\n", version);
+ return FALSE;
+}
+
+//we're not going to change icdTable at runtime, so callback is unused
+PICDTABLE APIENTRY DrvSetContext(HDC hdc, HGLRC hglrc, void *callback)
+{
+ ContextInfo *pContext;
+ WindowInfo *pWindowInfo;
+ BOOL ret = false;
+
+ CR_DDI_PROLOGUE();
+
+ (void) (callback);
+
+ crHashtableLock(stub.windowTable);
+ crHashtableLock(stub.contextTable);
+
+ pContext = (ContextInfo *) crHashtableSearch(stub.contextTable, (unsigned long) hglrc);
+ if (pContext)
+ {
+ pWindowInfo = stubGetWindowInfo(hdc);
+ if (pWindowInfo)
+ ret = stubMakeCurrent(pWindowInfo, pContext);
+ else
+ crError("no window info available.");
+ }
+ else
+ crError("No context found.");
+
+ crHashtableUnlock(stub.contextTable);
+ crHashtableUnlock(stub.windowTable);
+
+ return ret ? &icdTable : NULL;
+}
+
+BOOL APIENTRY DrvSetPixelFormat(HDC hdc, int iPixelFormat)
+{
+ CR_DDI_PROLOGUE();
+ crDebug( "DrvSetPixelFormat(0x%x, %i) called.", hdc, iPixelFormat );
+
+ if ( (iPixelFormat<1) || (iPixelFormat>2) ) {
+ crError( "wglSetPixelFormat: iPixelFormat=%d?", iPixelFormat );
+ }
+
+ return 1;
+}
+
+HGLRC APIENTRY DrvCreateContext(HDC hdc)
+{
+ char dpyName[MAX_DPY_NAME];
+ ContextInfo *context;
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ PVBOXUHGSMI pHgsmi = NULL;
+#endif
+
+ CR_DDI_PROLOGUE();
+
+ crDebug( "DrvCreateContext(0x%x) called.", hdc);
+
+ stubInit();
+
+ CRASSERT(stub.contextTable);
+
+ sprintf(dpyName, "%p", hdc);
+#ifndef VBOX_CROGL_USE_VBITS_SUPERSET
+ if (stub.haveNativeOpenGL)
+ desiredVisual |= ComputeVisBits( hdc );
+#endif
+
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ pHgsmi = VBoxCrHgsmiCreate();
+#endif
+
+ context = stubNewContext(dpyName, desiredVisual, UNDECIDED, 0
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , pHgsmi
+#endif
+ );
+ if (!context)
+ return 0;
+
+ return (HGLRC) context->id;
+}
+
+HGLRC APIENTRY DrvCreateLayerContext(HDC hdc, int iLayerPlane)
+{
+ CR_DDI_PROLOGUE();
+ crDebug( "DrvCreateLayerContext(0x%x, %i) called.", hdc, iLayerPlane);
+ //We don't support more than 1 layers.
+ if (iLayerPlane == 0) {
+ return DrvCreateContext(hdc);
+ } else {
+ crError( "DrvCreateLayerContext (%x,%x): unsupported", hdc, iLayerPlane);
+ return NULL;
+ }
+
+}
+
+BOOL APIENTRY DrvDescribeLayerPlane(HDC hdc,int iPixelFormat,
+ int iLayerPlane, UINT nBytes,
+ LPLAYERPLANEDESCRIPTOR plpd)
+{
+ CR_DDI_PROLOGUE();
+ crWarning( "DrvDescribeLayerPlane: unimplemented" );
+ CRASSERT(false);
+ return 0;
+}
+
+int APIENTRY DrvGetLayerPaletteEntries(HDC hdc, int iLayerPlane,
+ int iStart, int cEntries,
+ COLORREF *pcr)
+{
+ CR_DDI_PROLOGUE();
+ crWarning( "DrvGetLayerPaletteEntries: unsupported" );
+ CRASSERT(false);
+ return 0;
+}
+
+int APIENTRY DrvDescribePixelFormat(HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR pfd)
+{
+ CR_DDI_PROLOGUE();
+ if ( !pfd ) {
+ return 2;
+ }
+
+ if ( nBytes != sizeof(*pfd) ) {
+ crWarning( "DrvDescribePixelFormat: nBytes=%u?", nBytes );
+ return 2;
+ }
+
+ if (iPixelFormat==1)
+ {
+ crMemZero(pfd, sizeof(*pfd));
+
+ pfd->nSize = sizeof(*pfd);
+ pfd->nVersion = 1;
+ pfd->dwFlags = (PFD_DRAW_TO_WINDOW |
+ PFD_SUPPORT_OPENGL |
+ PFD_DOUBLEBUFFER);
+
+ pfd->dwFlags |= 0x8000; /* <- Needed for VSG Open Inventor to be happy */
+
+ pfd->iPixelType = PFD_TYPE_RGBA;
+ pfd->cColorBits = 32;
+ pfd->cRedBits = 8;
+ pfd->cRedShift = 24;
+ pfd->cGreenBits = 8;
+ pfd->cGreenShift = 16;
+ pfd->cBlueBits = 8;
+ pfd->cBlueShift = 8;
+ pfd->cAlphaBits = 8;
+ pfd->cAlphaShift = 0;
+ pfd->cAccumBits = 0;
+ pfd->cAccumRedBits = 0;
+ pfd->cAccumGreenBits = 0;
+ pfd->cAccumBlueBits = 0;
+ pfd->cAccumAlphaBits = 0;
+ pfd->cDepthBits = 32;
+ pfd->cStencilBits = 8;
+ pfd->cAuxBuffers = 0;
+ pfd->iLayerType = PFD_MAIN_PLANE;
+ pfd->bReserved = 0;
+ pfd->dwLayerMask = 0;
+ pfd->dwVisibleMask = 0;
+ pfd->dwDamageMask = 0;
+ }
+ else
+ {
+ crMemZero(pfd, sizeof(*pfd));
+ pfd->nVersion = 1;
+ pfd->dwFlags = (PFD_DRAW_TO_WINDOW|
+ PFD_SUPPORT_OPENGL);
+
+ pfd->iPixelType = PFD_TYPE_RGBA;
+ pfd->cColorBits = 32;
+ pfd->cRedBits = 8;
+ pfd->cRedShift = 16;
+ pfd->cGreenBits = 8;
+ pfd->cGreenShift = 8;
+ pfd->cBlueBits = 8;
+ pfd->cBlueShift = 0;
+ pfd->cAlphaBits = 0;
+ pfd->cAlphaShift = 0;
+ pfd->cAccumBits = 64;
+ pfd->cAccumRedBits = 16;
+ pfd->cAccumGreenBits = 16;
+ pfd->cAccumBlueBits = 16;
+ pfd->cAccumAlphaBits = 0;
+ pfd->cDepthBits = 16;
+ pfd->cStencilBits = 8;
+ pfd->cAuxBuffers = 0;
+ pfd->iLayerType = PFD_MAIN_PLANE;
+ pfd->bReserved = 0;
+ pfd->dwLayerMask = 0;
+ pfd->dwVisibleMask = 0;
+ pfd->dwDamageMask = 0;
+ }
+
+ /* the max PFD index */
+ return 2;
+}
+
+BOOL APIENTRY DrvDeleteContext(HGLRC hglrc)
+{
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ ContextInfo *pContext;
+ PVBOXUHGSMI pHgsmi = NULL;
+#endif
+
+ CR_DDI_PROLOGUE();
+ crDebug( "DrvDeleteContext(0x%x) called", hglrc );
+
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ crHashtableLock(stub.contextTable);
+
+ pContext = (ContextInfo *) crHashtableSearch(stub.contextTable, (unsigned long) hglrc);
+ if (pContext)
+ pHgsmi = pContext->pHgsmi;
+
+ crHashtableUnlock(stub.contextTable);
+#endif
+
+ stubDestroyContext( (unsigned long) hglrc );
+
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ if (pHgsmi)
+ VBoxCrHgsmiDestroy(pHgsmi);
+#endif
+
+ return true;
+}
+
+BOOL APIENTRY DrvCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask)
+{
+ CR_DDI_PROLOGUE();
+ crWarning( "DrvCopyContext: unsupported" );
+ return 0;
+}
+
+DECLEXPORT(BOOL) WINAPI wglShareLists_prox( HGLRC hglrc1, HGLRC hglrc2 );
+
+BOOL APIENTRY DrvShareLists(HGLRC hglrc1, HGLRC hglrc2)
+{
+ return wglShareLists_prox(hglrc1, hglrc2);
+}
+
+int APIENTRY DrvSetLayerPaletteEntries(HDC hdc, int iLayerPlane,
+ int iStart, int cEntries,
+ CONST COLORREF *pcr)
+{
+ CR_DDI_PROLOGUE();
+ crWarning( "DrvSetLayerPaletteEntries: unsupported" );
+ return 0;
+}
+
+
+BOOL APIENTRY DrvRealizeLayerPalette(HDC hdc, int iLayerPlane, BOOL bRealize)
+{
+ CR_DDI_PROLOGUE();
+ crWarning( "DrvRealizeLayerPalette: unsupported" );
+ return 0;
+}
+
+BOOL APIENTRY DrvSwapLayerBuffers(HDC hdc, UINT fuPlanes)
+{
+ CR_DDI_PROLOGUE();
+ if (fuPlanes == 1)
+ {
+ return DrvSwapBuffers(hdc);
+ }
+ else
+ {
+ crWarning( "DrvSwapLayerBuffers: unsupported" );
+ CRASSERT(false);
+ return 0;
+ }
+}
+
+BOOL APIENTRY DrvSwapBuffers(HDC hdc)
+{
+ WindowInfo *window;
+
+ CR_DDI_PROLOGUE();
+ /*crDebug( "DrvSwapBuffers(0x%x) called", hdc );*/
+ window = stubGetWindowInfo(hdc);
+ stubSwapBuffers( window, 0 );
+ return 1;
+}
+
diff --git a/src/VBox/Additions/common/crOpenGL/icd_drv.h b/src/VBox/Additions/common/crOpenGL/icd_drv.h
new file mode 100644
index 00000000..97004bdd
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/icd_drv.h
@@ -0,0 +1,55 @@
+/* $Id: icd_drv.h $ */
+/** @file
+ * VirtualBox Windows NT/2000/XP guest OpenGL ICD header
+ */
+
+/*
+ * Copyright (C) 2006-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#ifndef GA_INCLUDED_SRC_common_crOpenGL_icd_drv_h
+#define GA_INCLUDED_SRC_common_crOpenGL_icd_drv_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include <iprt/win/windows.h>
+
+typedef struct ICDTABLE
+{
+ DWORD size;
+ PROC table[336];
+} ICDTABLE, *PICDTABLE;
+
+void APIENTRY DrvReleaseContext(HGLRC hglrc);
+BOOL APIENTRY DrvValidateVersion(DWORD version);
+PICDTABLE APIENTRY DrvSetContext(HDC hdc, HGLRC hglrc, void *callback);
+BOOL APIENTRY DrvSetPixelFormat(HDC hdc, int iPixelFormat);
+HGLRC APIENTRY DrvCreateContext(HDC hdc);
+HGLRC APIENTRY DrvCreateLayerContext(HDC hdc, int iLayerPlane);
+BOOL APIENTRY DrvDescribeLayerPlane(HDC hdc,int iPixelFormat,
+ int iLayerPlane, UINT nBytes,
+ LPLAYERPLANEDESCRIPTOR plpd);
+int APIENTRY DrvGetLayerPaletteEntries(HDC hdc, int iLayerPlane,
+ int iStart, int cEntries,
+ COLORREF *pcr);
+int APIENTRY DrvDescribePixelFormat(HDC hdc, int iPixelFormat, UINT nBytes, LPPIXELFORMATDESCRIPTOR pfd);
+BOOL APIENTRY DrvDeleteContext(HGLRC hglrc);
+BOOL APIENTRY DrvCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask);
+BOOL APIENTRY DrvShareLists(HGLRC hglrc1, HGLRC hglrc2);
+int APIENTRY DrvSetLayerPaletteEntries(HDC hdc, int iLayerPlane,
+ int iStart, int cEntries,
+ CONST COLORREF *pcr);
+BOOL APIENTRY DrvRealizeLayerPalette(HDC hdc, int iLayerPlane, BOOL bRealize);
+BOOL APIENTRY DrvSwapLayerBuffers(HDC hdc, UINT fuPlanes);
+BOOL APIENTRY DrvSwapBuffers(HDC hdc);
+
+#endif /* !GA_INCLUDED_SRC_common_crOpenGL_icd_drv_h */
diff --git a/src/VBox/Additions/common/crOpenGL/load.c b/src/VBox/Additions/common/crOpenGL/load.c
new file mode 100644
index 00000000..a4b0cf8c
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/load.c
@@ -0,0 +1,1526 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "cr_spu.h"
+#include "cr_net.h"
+#include "cr_error.h"
+#include "cr_mem.h"
+#include "cr_string.h"
+#include "cr_net.h"
+#include "cr_environment.h"
+#include "cr_process.h"
+#include "cr_rand.h"
+#include "cr_netserver.h"
+#include "stub.h"
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <iprt/initterm.h>
+#include <iprt/thread.h>
+#include <iprt/errcore.h>
+#include <iprt/asm.h>
+#ifndef WINDOWS
+# include <sys/types.h>
+# include <unistd.h>
+#endif
+
+#ifdef VBOX_WITH_WDDM
+#include <d3d9types.h>
+#include <D3dumddi.h>
+#endif
+
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+# include <VBoxCrHgsmi.h>
+#endif
+
+/**
+ * If you change this, see the comments in tilesortspu_context.c
+ */
+#define MAGIC_CONTEXT_BASE 500
+
+#define CONFIG_LOOKUP_FILE ".crconfigs"
+
+#ifdef WINDOWS
+#define PYTHON_EXE "python.exe"
+#else
+#define PYTHON_EXE "python"
+#endif
+
+static bool stub_initialized = 0;
+#ifdef WINDOWS
+static CRmutex stub_init_mutex;
+#define STUB_INIT_LOCK() do { crLockMutex(&stub_init_mutex); } while (0)
+#define STUB_INIT_UNLOCK() do { crUnlockMutex(&stub_init_mutex); } while (0)
+#else
+#define STUB_INIT_LOCK() do { } while (0)
+#define STUB_INIT_UNLOCK() do { } while (0)
+#endif
+
+/* NOTE: 'SPUDispatchTable glim' is declared in NULLfuncs.py now */
+/* NOTE: 'SPUDispatchTable stubThreadsafeDispatch' is declared in tsfuncs.c */
+Stub stub;
+#ifdef CHROMIUM_THREADSAFE
+static bool g_stubIsCurrentContextTSDInited;
+CRtsd g_stubCurrentContextTSD;
+#endif
+
+
+#ifndef VBOX_NO_NATIVEGL
+static void stubInitNativeDispatch( void )
+{
+# define MAX_FUNCS 1000
+ SPUNamedFunctionTable gl_funcs[MAX_FUNCS];
+ int numFuncs;
+
+ numFuncs = crLoadOpenGL( &stub.wsInterface, gl_funcs );
+
+ stub.haveNativeOpenGL = (numFuncs > 0);
+
+ /* XXX call this after context binding */
+ numFuncs += crLoadOpenGLExtensions( &stub.wsInterface, gl_funcs + numFuncs );
+
+ CRASSERT(numFuncs < MAX_FUNCS);
+
+ crSPUInitDispatchTable( &stub.nativeDispatch );
+ crSPUInitDispatch( &stub.nativeDispatch, gl_funcs );
+ crSPUInitDispatchNops( &stub.nativeDispatch );
+# undef MAX_FUNCS
+}
+#endif /* !VBOX_NO_NATIVEGL */
+
+
+/** Pointer to the SPU's real glClear and glViewport functions */
+static ClearFunc_t origClear;
+static ViewportFunc_t origViewport;
+static SwapBuffersFunc_t origSwapBuffers;
+static DrawBufferFunc_t origDrawBuffer;
+static ScissorFunc_t origScissor;
+
+static void stubCheckWindowState(WindowInfo *window, GLboolean bFlushOnChange)
+{
+ bool bForceUpdate = false;
+ bool bChanged = false;
+
+#ifdef WINDOWS
+ /** @todo install hook and track for WM_DISPLAYCHANGE */
+ {
+ DEVMODE devMode;
+
+ devMode.dmSize = sizeof(DEVMODE);
+ EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devMode);
+
+ if (devMode.dmPelsWidth!=window->dmPelsWidth || devMode.dmPelsHeight!=window->dmPelsHeight)
+ {
+ crDebug("Resolution changed(%d,%d), forcing window Pos/Size update", devMode.dmPelsWidth, devMode.dmPelsHeight);
+ window->dmPelsWidth = devMode.dmPelsWidth;
+ window->dmPelsHeight = devMode.dmPelsHeight;
+ bForceUpdate = true;
+ }
+ }
+#endif
+
+ bChanged = stubUpdateWindowGeometry(window, bForceUpdate) || bForceUpdate;
+
+#if defined(GLX) || defined (WINDOWS)
+ if (stub.trackWindowVisibleRgn)
+ {
+ bChanged = stubUpdateWindowVisibileRegions(window) || bChanged;
+ }
+#endif
+
+ if (stub.trackWindowVisibility && window->type == CHROMIUM && window->drawable) {
+ const int mapped = stubIsWindowVisible(window);
+ if (mapped != window->mapped) {
+ crDebug("Dispatched: WindowShow(%i, %i)", window->spuWindow, mapped);
+ stub.spu->dispatch_table.WindowShow(window->spuWindow, mapped);
+ window->mapped = mapped;
+ bChanged = true;
+ }
+ }
+
+ if (bFlushOnChange && bChanged)
+ {
+ stub.spu->dispatch_table.Flush();
+ }
+}
+
+static bool stubSystemWindowExist(WindowInfo *pWindow)
+{
+#ifdef WINDOWS
+ if (pWindow->hWnd!=WindowFromDC(pWindow->drawable))
+ {
+ return false;
+ }
+#else
+ Window root;
+ int x, y;
+ unsigned int border, depth, w, h;
+ Display *dpy;
+
+ dpy = stubGetWindowDisplay(pWindow);
+
+ XLOCK(dpy);
+ if (!XGetGeometry(dpy, pWindow->drawable, &root, &x, &y, &w, &h, &border, &depth))
+ {
+ XUNLOCK(dpy);
+ return false;
+ }
+ XUNLOCK(dpy);
+#endif
+
+ return true;
+}
+
+static void stubCheckWindowsCB(unsigned long key, void *data1, void *data2)
+{
+ WindowInfo *pWindow = (WindowInfo *) data1;
+ ContextInfo *pCtx = (ContextInfo *) data2;
+ (void)key;
+
+ if (pWindow == pCtx->currentDrawable
+ || pWindow->type!=CHROMIUM
+ || pWindow->pOwner!=pCtx)
+ {
+ return;
+ }
+
+ if (!stubSystemWindowExist(pWindow))
+ {
+#ifdef WINDOWS
+ stubDestroyWindow(CR_CTX_CON(pCtx), (GLint)pWindow->hWnd);
+#else
+ stubDestroyWindow(CR_CTX_CON(pCtx), (GLint)pWindow->drawable);
+#endif
+ return;
+ }
+
+ stubCheckWindowState(pWindow, GL_FALSE);
+}
+
+static void stubCheckWindowsState(void)
+{
+ ContextInfo *context = stubGetCurrentContext();
+
+ CRASSERT(stub.trackWindowSize || stub.trackWindowPos);
+
+ if (!context)
+ return;
+
+#if defined(WINDOWS) && defined(VBOX_WITH_WDDM)
+ if (stub.bRunningUnderWDDM)
+ return;
+#endif
+
+ /* Try to keep a consistent locking order. */
+ crHashtableLock(stub.windowTable);
+#if defined(CR_NEWWINTRACK) && !defined(WINDOWS)
+ crLockMutex(&stub.mutex);
+#endif
+
+ stubCheckWindowState(context->currentDrawable, GL_TRUE);
+ crHashtableWalkUnlocked(stub.windowTable, stubCheckWindowsCB, context);
+
+#if defined(CR_NEWWINTRACK) && !defined(WINDOWS)
+ crUnlockMutex(&stub.mutex);
+#endif
+ crHashtableUnlock(stub.windowTable);
+}
+
+
+/**
+ * Override the head SPU's glClear function.
+ * We're basically trapping this function so that we can poll the
+ * application window size at a regular interval.
+ */
+static void SPU_APIENTRY trapClear(GLbitfield mask)
+{
+ stubCheckWindowsState();
+ /* call the original SPU glClear function */
+ origClear(mask);
+}
+
+/**
+ * As above, but for glViewport. Most apps call glViewport before
+ * glClear when a window is resized.
+ */
+static void SPU_APIENTRY trapViewport(GLint x, GLint y, GLsizei w, GLsizei h)
+{
+ stubCheckWindowsState();
+ /* call the original SPU glViewport function */
+ origViewport(x, y, w, h);
+}
+
+/*static void SPU_APIENTRY trapSwapBuffers(GLint window, GLint flags)
+{
+ stubCheckWindowsState();
+ origSwapBuffers(window, flags);
+}
+
+static void SPU_APIENTRY trapDrawBuffer(GLenum buf)
+{
+ stubCheckWindowsState();
+ origDrawBuffer(buf);
+}*/
+
+#if 0 /* unused */
+static void SPU_APIENTRY trapScissor(GLint x, GLint y, GLsizei w, GLsizei h)
+{
+ int winX, winY;
+ unsigned int winW, winH;
+ WindowInfo *pWindow;
+ ContextInfo *context = stubGetCurrentContext();
+ (void)x; (void)y; (void)w; (void)h;
+
+ pWindow = context->currentDrawable;
+ stubGetWindowGeometry(pWindow, &winX, &winY, &winW, &winH);
+ origScissor(0, 0, winW, winH);
+}
+#endif /* unused */
+
+/**
+ * Use the GL function pointers in \<spu\> to initialize the static glim
+ * dispatch table.
+ */
+static void stubInitSPUDispatch(SPU *spu)
+{
+ crSPUInitDispatchTable( &stub.spuDispatch );
+ crSPUCopyDispatchTable( &stub.spuDispatch, &(spu->dispatch_table) );
+
+ if (stub.trackWindowSize || stub.trackWindowPos || stub.trackWindowVisibleRgn) {
+ /* patch-in special glClear/Viewport function to track window sizing */
+ origClear = stub.spuDispatch.Clear;
+ origViewport = stub.spuDispatch.Viewport;
+ origSwapBuffers = stub.spuDispatch.SwapBuffers;
+ origDrawBuffer = stub.spuDispatch.DrawBuffer;
+ origScissor = stub.spuDispatch.Scissor;
+ stub.spuDispatch.Clear = trapClear;
+ stub.spuDispatch.Viewport = trapViewport;
+
+ /*stub.spuDispatch.SwapBuffers = trapSwapBuffers;
+ stub.spuDispatch.DrawBuffer = trapDrawBuffer;*/
+ }
+
+ crSPUCopyDispatchTable( &glim, &stub.spuDispatch );
+}
+
+#if 0 /** @todo stubSPUTearDown & stubSPUTearDownLocked are not referenced */
+
+// Callback function, used to destroy all created contexts
+static void hsWalkStubDestroyContexts(unsigned long key, void *data1, void *data2)
+{
+ (void)data1; (void)data2;
+ stubDestroyContext(key);
+}
+
+/**
+ * This is called when we exit.
+ * We call all the SPU's cleanup functions.
+ */
+static void stubSPUTearDownLocked(void)
+{
+ crDebug("stubSPUTearDownLocked");
+
+#ifdef WINDOWS
+# ifndef CR_NEWWINTRACK
+ stubUninstallWindowMessageHook();
+# endif
+#endif
+
+#ifdef CR_NEWWINTRACK
+ ASMAtomicWriteBool(&stub.bShutdownSyncThread, true);
+#endif
+
+ //delete all created contexts
+ stubMakeCurrent( NULL, NULL);
+
+ /* the lock order is windowTable->contextTable (see wglMakeCurrent_prox, glXMakeCurrent)
+ * this is why we need to take a windowTable lock since we will later do stub.windowTable access & locking */
+ crHashtableLock(stub.windowTable);
+ crHashtableWalk(stub.contextTable, hsWalkStubDestroyContexts, NULL);
+ crHashtableUnlock(stub.windowTable);
+
+ /* shutdown, now trap any calls to a NULL dispatcher */
+ crSPUCopyDispatchTable(&glim, &stubNULLDispatch);
+
+ crSPUUnloadChain(stub.spu);
+ stub.spu = NULL;
+
+#ifndef Linux
+ crUnloadOpenGL();
+#endif
+
+#ifndef WINDOWS
+ crNetTearDown();
+#endif
+
+#ifdef GLX
+ if (stub.xshmSI.shmid>=0)
+ {
+ shmctl(stub.xshmSI.shmid, IPC_RMID, 0);
+ shmdt(stub.xshmSI.shmaddr);
+ }
+ crFreeHashtable(stub.pGLXPixmapsHash, crFree);
+#endif
+
+ crFreeHashtable(stub.windowTable, crFree);
+ crFreeHashtable(stub.contextTable, NULL);
+
+ crMemset(&stub, 0, sizeof(stub));
+
+}
+
+/**
+ * This is called when we exit.
+ * We call all the SPU's cleanup functions.
+ */
+static void stubSPUTearDown(void)
+{
+ STUB_INIT_LOCK();
+ if (stub_initialized)
+ {
+ stubSPUTearDownLocked();
+ stub_initialized = 0;
+ }
+ STUB_INIT_UNLOCK();
+}
+
+#endif /** @todo stubSPUTearDown & stubSPUTearDownLocked are not referenced */
+
+static void stubSPUSafeTearDown(void)
+{
+#ifdef CHROMIUM_THREADSAFE
+ CRmutex *mutex;
+#endif
+
+ if (!stub_initialized) return;
+ stub_initialized = 0;
+
+#ifdef CHROMIUM_THREADSAFE
+ mutex = &stub.mutex;
+ crLockMutex(mutex);
+#endif
+ crDebug("stubSPUSafeTearDown");
+
+#ifdef WINDOWS
+# ifndef CR_NEWWINTRACK
+ stubUninstallWindowMessageHook();
+# endif
+#endif
+
+#if defined(CR_NEWWINTRACK)
+ crUnlockMutex(mutex);
+# if defined(WINDOWS)
+ if (stub.hSyncThread && RTThreadGetState(stub.hSyncThread)!=RTTHREADSTATE_TERMINATED)
+ {
+ HANDLE hNative;
+ DWORD ec=0;
+
+ hNative = OpenThread(SYNCHRONIZE|THREAD_QUERY_INFORMATION|THREAD_TERMINATE,
+ false, RTThreadGetNative(stub.hSyncThread));
+ if (!hNative)
+ {
+ crWarning("Failed to get handle for sync thread(%#x)", GetLastError());
+ }
+ else
+ {
+ crDebug("Got handle %p for thread %#x", hNative, RTThreadGetNative(stub.hSyncThread));
+ }
+
+ ASMAtomicWriteBool(&stub.bShutdownSyncThread, true);
+
+ if (PostThreadMessage(RTThreadGetNative(stub.hSyncThread), WM_QUIT, 0, 0))
+ {
+ RTThreadWait(stub.hSyncThread, 1000, NULL);
+
+ /*Same issue as on linux, RTThreadWait exits before system thread is terminated, which leads
+ * to issues as our dll goes to be unloaded.
+ *@todo
+ *We usually call this function from DllMain which seems to be holding some lock and thus we have to
+ * kill thread via TerminateThread.
+ */
+ if (WaitForSingleObject(hNative, 100)==WAIT_TIMEOUT)
+ {
+ crDebug("Wait failed, terminating");
+ if (!TerminateThread(hNative, 1))
+ {
+ crDebug("TerminateThread failed");
+ }
+ }
+ if (GetExitCodeThread(hNative, &ec))
+ {
+ crDebug("Thread %p exited with ec=%i", hNative, ec);
+ }
+ else
+ {
+ crDebug("GetExitCodeThread failed(%#x)", GetLastError());
+ }
+ }
+ else
+ {
+ crDebug("Sync thread killed before DLL_PROCESS_DETACH");
+ }
+
+ if (hNative)
+ {
+ CloseHandle(hNative);
+ }
+ }
+#else
+ if (stub.hSyncThread!=NIL_RTTHREAD)
+ {
+ ASMAtomicWriteBool(&stub.bShutdownSyncThread, true);
+ {
+ int rc = RTThreadWait(stub.hSyncThread, RT_INDEFINITE_WAIT, NULL);
+ if (RT_FAILURE(rc))
+ {
+ WARN(("RTThreadWait_join failed %i", rc));
+ }
+ }
+ }
+#endif
+ crLockMutex(mutex);
+#endif
+
+#ifndef WINDOWS
+ crNetTearDown();
+#endif
+
+#ifdef CHROMIUM_THREADSAFE
+ crUnlockMutex(mutex);
+ crFreeMutex(mutex);
+#endif
+ crMemset(&stub, 0, sizeof(stub));
+}
+
+
+static void stubExitHandler(void)
+{
+ stubSPUSafeTearDown();
+ signal(SIGTERM, SIG_DFL);
+ signal(SIGINT, SIG_DFL);
+}
+
+/**
+ * Called when we receive a SIGTERM signal.
+ */
+static void stubSignalHandler(int signo)
+{
+ (void)signo;
+ stubSPUSafeTearDown();
+ exit(0); /* this causes stubExitHandler() to be called */
+}
+
+#ifndef RT_OS_WINDOWS
+# ifdef CHROMIUM_THREADSAFE
+static void stubThreadTlsDtor(void *pvValue)
+{
+ ContextInfo *pCtx = (ContextInfo*)pvValue;
+ VBoxTlsRefRelease(pCtx);
+}
+# endif
+#endif
+
+
+/**
+ * Init variables in the stub structure, install signal handler.
+ */
+static void stubInitVars(void)
+{
+ WindowInfo *defaultWin;
+
+#ifdef CHROMIUM_THREADSAFE
+ crInitMutex(&stub.mutex);
+#endif
+
+ /* At the very least we want CR_RGB_BIT. */
+ stub.haveNativeOpenGL = GL_FALSE;
+ stub.spu = NULL;
+ stub.appDrawCursor = 0;
+ stub.minChromiumWindowWidth = 0;
+ stub.minChromiumWindowHeight = 0;
+ stub.maxChromiumWindowWidth = 0;
+ stub.maxChromiumWindowHeight = 0;
+ stub.matchChromiumWindowCount = 0;
+ stub.matchChromiumWindowID = NULL;
+ stub.matchWindowTitle = NULL;
+ stub.ignoreFreeglutMenus = 0;
+ stub.threadSafe = GL_FALSE;
+ stub.trackWindowSize = 0;
+ stub.trackWindowPos = 0;
+ stub.trackWindowVisibility = 0;
+ stub.trackWindowVisibleRgn = 0;
+ stub.mothershipPID = 0;
+ stub.spu_dir = NULL;
+
+ stub.freeContextNumber = MAGIC_CONTEXT_BASE;
+ stub.contextTable = crAllocHashtable();
+#ifndef RT_OS_WINDOWS
+# ifdef CHROMIUM_THREADSAFE
+ if (!g_stubIsCurrentContextTSDInited)
+ {
+ crInitTSDF(&g_stubCurrentContextTSD, stubThreadTlsDtor);
+ g_stubIsCurrentContextTSDInited = true;
+ }
+# endif
+#endif
+ stubSetCurrentContext(NULL);
+
+ stub.windowTable = crAllocHashtable();
+
+#ifdef CR_NEWWINTRACK
+ stub.bShutdownSyncThread = false;
+ stub.hSyncThread = NIL_RTTHREAD;
+#endif
+
+ defaultWin = (WindowInfo *) crCalloc(sizeof(WindowInfo));
+ defaultWin->type = CHROMIUM;
+ defaultWin->spuWindow = 0; /* window 0 always exists */
+#ifdef WINDOWS
+ defaultWin->hVisibleRegion = INVALID_HANDLE_VALUE;
+#elif defined(GLX)
+ defaultWin->pVisibleRegions = NULL;
+ defaultWin->cVisibleRegions = 0;
+#endif
+ crHashtableAdd(stub.windowTable, 0, defaultWin);
+
+#if 1
+ atexit(stubExitHandler);
+ signal(SIGTERM, stubSignalHandler);
+ signal(SIGINT, stubSignalHandler);
+#ifndef WINDOWS
+ signal(SIGPIPE, SIG_IGN); /* the networking code should catch this */
+#endif
+#else
+ (void) stubExitHandler;
+ (void) stubSignalHandler;
+#endif
+}
+
+
+#if 0 /* unused */
+
+/**
+ * Return a free port number for the mothership to use, or -1 if we
+ * can't find one.
+ */
+static int
+GenerateMothershipPort(void)
+{
+ const int MAX_PORT = 10100;
+ unsigned short port;
+
+ /* generate initial port number randomly */
+ crRandAutoSeed();
+ port = (unsigned short) crRandInt(10001, MAX_PORT);
+
+#ifdef WINDOWS
+ /* XXX should implement a free port check here */
+ return port;
+#else
+ /*
+ * See if this port number really is free, try another if needed.
+ */
+ {
+ struct sockaddr_in servaddr;
+ int so_reuseaddr = 1;
+ int sock, k;
+
+ /* create socket */
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+ CRASSERT(sock > 2);
+
+ /* deallocate socket/port when we exit */
+ k = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
+ (char *) &so_reuseaddr, sizeof(so_reuseaddr));
+ CRASSERT(k == 0);
+
+ /* initialize the servaddr struct */
+ crMemset(&servaddr, 0, sizeof(servaddr) );
+ servaddr.sin_family = AF_INET;
+ servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+
+ while (port < MAX_PORT) {
+ /* Bind to the given port number, return -1 if we fail */
+ servaddr.sin_port = htons((unsigned short) port);
+ k = bind(sock, (struct sockaddr *) &servaddr, sizeof(servaddr));
+ if (k) {
+ /* failed to create port. try next one. */
+ port++;
+ }
+ else {
+ /* free the socket/port now so mothership can make it */
+ close(sock);
+ return port;
+ }
+ }
+ }
+#endif /* WINDOWS */
+ return -1;
+}
+
+
+/**
+ * Try to determine which mothership configuration to use for this program.
+ */
+static char **
+LookupMothershipConfig(const char *procName)
+{
+ const int procNameLen = crStrlen(procName);
+ FILE *f;
+ const char *home;
+ char configPath[1000];
+
+ /* first, check if the CR_CONFIG env var is set */
+ {
+ const char *conf = crGetenv("CR_CONFIG");
+ if (conf && crStrlen(conf) > 0)
+ return crStrSplit(conf, " ");
+ }
+
+ /* second, look up config name from config file */
+ home = crGetenv("HOME");
+ if (home)
+ sprintf(configPath, "%s/%s", home, CONFIG_LOOKUP_FILE);
+ else
+ crStrcpy(configPath, CONFIG_LOOKUP_FILE); /* from current dir */
+ /* Check if the CR_CONFIG_PATH env var is set. */
+ {
+ const char *conf = crGetenv("CR_CONFIG_PATH");
+ if (conf)
+ crStrcpy(configPath, conf); /* from env var */
+ }
+
+ f = fopen(configPath, "r");
+ if (!f) {
+ return NULL;
+ }
+
+ while (!feof(f)) {
+ char line[1000];
+ char **args;
+ fgets(line, 999, f);
+ line[crStrlen(line) - 1] = 0; /* remove trailing newline */
+ if (crStrncmp(line, procName, procNameLen) == 0 &&
+ (line[procNameLen] == ' ' || line[procNameLen] == '\t'))
+ {
+ crWarning("Using Chromium configuration for %s from %s",
+ procName, configPath);
+ args = crStrSplit(line + procNameLen + 1, " ");
+ return args;
+ }
+ }
+ fclose(f);
+ return NULL;
+}
+
+
+static int Mothership_Awake = 0;
+
+
+/**
+ * Signal handler to determine when mothership is ready.
+ */
+static void
+MothershipPhoneHome(int signo)
+{
+ crDebug("Got signal %d: mothership is awake!", signo);
+ Mothership_Awake = 1;
+}
+
+#endif /* 0 */
+
+static void stubSetDefaultConfigurationOptions(void)
+{
+ unsigned char key[16]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+ stub.appDrawCursor = 0;
+ stub.minChromiumWindowWidth = 0;
+ stub.minChromiumWindowHeight = 0;
+ stub.maxChromiumWindowWidth = 0;
+ stub.maxChromiumWindowHeight = 0;
+ stub.matchChromiumWindowID = NULL;
+ stub.numIgnoreWindowID = 0;
+ stub.matchWindowTitle = NULL;
+ stub.ignoreFreeglutMenus = 0;
+ stub.trackWindowSize = 1;
+ stub.trackWindowPos = 1;
+ stub.trackWindowVisibility = 1;
+ stub.trackWindowVisibleRgn = 1;
+ stub.matchChromiumWindowCount = 0;
+ stub.spu_dir = NULL;
+ crNetSetRank(0);
+ crNetSetContextRange(32, 35);
+ crNetSetNodeRange("iam0", "iamvis20");
+ crNetSetKey(key,sizeof(key));
+ stub.force_pbuffers = 0;
+
+#ifdef WINDOWS
+# ifdef VBOX_WITH_WDDM
+ stub.bRunningUnderWDDM = false;
+# endif
+#endif
+}
+
+#ifdef CR_NEWWINTRACK
+# ifdef VBOX_WITH_WDDM
+static void stubDispatchVisibleRegions(WindowInfo *pWindow)
+{
+ DWORD dwCount;
+ LPRGNDATA lpRgnData;
+
+ dwCount = GetRegionData(pWindow->hVisibleRegion, 0, NULL);
+ lpRgnData = crAlloc(dwCount);
+
+ if (lpRgnData)
+ {
+ GetRegionData(pWindow->hVisibleRegion, dwCount, lpRgnData);
+ crDebug("Dispatched WindowVisibleRegion (%i, cRects=%i)", pWindow->spuWindow, lpRgnData->rdh.nCount);
+ stub.spuDispatch.WindowVisibleRegion(pWindow->spuWindow, lpRgnData->rdh.nCount, (GLint*) lpRgnData->Buffer);
+ crFree(lpRgnData);
+ }
+ else crWarning("GetRegionData failed, VisibleRegions update failed");
+}
+
+# endif /* VBOX_WITH_WDDM */
+
+static void stubSyncTrCheckWindowsCB(unsigned long key, void *data1, void *data2)
+{
+ WindowInfo *pWindow = (WindowInfo *) data1;
+ (void)key; (void) data2;
+
+ if (pWindow->type!=CHROMIUM || pWindow->spuWindow==0)
+ {
+ return;
+ }
+
+ stub.spu->dispatch_table.VBoxPackSetInjectID(pWindow->u32ClientID);
+
+ if (!stubSystemWindowExist(pWindow))
+ {
+#ifdef WINDOWS
+ stubDestroyWindow(0, (GLint)pWindow->hWnd);
+#else
+ stubDestroyWindow(0, (GLint)pWindow->drawable);
+#endif
+ /*No need to flush here as crWindowDestroy does it*/
+ return;
+ }
+
+#if defined(WINDOWS) && defined(VBOX_WITH_WDDM)
+ if (stub.bRunningUnderWDDM)
+ return;
+#endif
+ stubCheckWindowState(pWindow, GL_TRUE);
+}
+
+static DECLCALLBACK(int) stubSyncThreadProc(RTTHREAD ThreadSelf, void *pvUser)
+{
+#ifdef WINDOWS
+ MSG msg;
+# ifdef VBOX_WITH_WDDM
+ HMODULE hVBoxD3D = NULL;
+ GLint spuConnection = 0;
+# endif
+#endif
+
+ (void) pvUser;
+
+ crDebug("Sync thread started");
+#ifdef WINDOWS
+ PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
+# ifdef VBOX_WITH_WDDM
+ hVBoxD3D = NULL;
+ if (!GetModuleHandleEx(0, VBOX_MODNAME_DISPD3D, &hVBoxD3D))
+ {
+ crDebug("GetModuleHandleEx failed err %d", GetLastError());
+ hVBoxD3D = NULL;
+ }
+
+ if (hVBoxD3D)
+ {
+ crDebug("running with " VBOX_MODNAME_DISPD3D);
+ stub.trackWindowVisibleRgn = 0;
+ stub.bRunningUnderWDDM = true;
+ }
+# endif /* VBOX_WITH_WDDM */
+#endif /* WINDOWS */
+
+ crLockMutex(&stub.mutex);
+#if defined(WINDOWS) && defined(VBOX_WITH_WDDM)
+ spuConnection =
+#endif
+ stub.spu->dispatch_table.VBoxPackSetInjectThread(NULL);
+#if defined(WINDOWS) && defined(VBOX_WITH_WDDM)
+ if (stub.bRunningUnderWDDM && !spuConnection)
+ {
+ crError("VBoxPackSetInjectThread failed!");
+ }
+#endif
+ crUnlockMutex(&stub.mutex);
+
+ RTThreadUserSignal(ThreadSelf);
+
+ while(!stub.bShutdownSyncThread)
+ {
+#ifdef WINDOWS
+ if (!PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
+ {
+# ifdef VBOX_WITH_WDDM
+ if (stub.bRunningUnderWDDM)
+ {
+
+ }
+ else
+# endif
+ {
+ crHashtableWalk(stub.windowTable, stubSyncTrCheckWindowsCB, NULL);
+ RTThreadSleep(50);
+ }
+ }
+ else
+ {
+ if (WM_QUIT==msg.message)
+ {
+ crDebug("Sync thread got WM_QUIT");
+ break;
+ }
+ else
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+#else
+ /* Try to keep a consistent locking order. */
+ crHashtableLock(stub.windowTable);
+ crLockMutex(&stub.mutex);
+ crHashtableWalkUnlocked(stub.windowTable, stubSyncTrCheckWindowsCB, NULL);
+ crUnlockMutex(&stub.mutex);
+ crHashtableUnlock(stub.windowTable);
+ RTThreadSleep(50);
+#endif
+ }
+
+#ifdef VBOX_WITH_WDDM
+ if (spuConnection)
+ {
+ stub.spu->dispatch_table.VBoxConDestroy(spuConnection);
+ }
+ if (hVBoxD3D)
+ {
+ FreeLibrary(hVBoxD3D);
+ }
+#endif
+ crDebug("Sync thread stopped");
+ return 0;
+}
+#endif /* CR_NEWWINTRACK */
+
+/**
+ * Do one-time initializations for the faker.
+ * Returns TRUE on success, FALSE otherwise.
+ */
+static bool
+stubInitLocked(void)
+{
+ /* Here is where we contact the mothership to find out what we're supposed
+ * to be doing. Networking code in a DLL initializer. I sure hope this
+ * works :)
+ *
+ * HOW can I pass the mothership address to this if I already know it?
+ */
+
+ char response[1024];
+ char **spuchain;
+ int num_spus;
+ int *spu_ids;
+ char **spu_names;
+ const char *app_id;
+ int i;
+ int disable_sync = 0;
+#if defined(WINDOWS) && defined(VBOX_WITH_WDDM)
+ HMODULE hVBoxD3D = NULL;
+#endif
+
+ stubInitVars();
+
+ crGetProcName(response, 1024);
+ crDebug("Stub launched for %s", response);
+
+#if defined(CR_NEWWINTRACK) && !defined(WINDOWS)
+ /** @todo when vm boots with compiz turned on, new code causes hang in xcb_wait_for_reply in the sync thread
+ * as at the start compiz runs our code under XGrabServer.
+ */
+ if (!crStrcmp(response, "compiz") || !crStrcmp(response, "compiz_real") || !crStrcmp(response, "compiz.real")
+ || !crStrcmp(response, "compiz-bin"))
+ {
+ disable_sync = 1;
+ }
+#endif
+
+ /** @todo check if it'd be of any use on other than guests, no use for windows */
+ app_id = crGetenv( "CR_APPLICATION_ID_NUMBER" );
+
+ crNetInit( NULL, NULL );
+
+#ifndef WINDOWS
+ {
+ CRNetServer ns;
+
+ ns.name = "vboxhgcm://host:0";
+ ns.buffer_size = 1024;
+ crNetServerConnect(&ns
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , NULL
+#endif
+ );
+ if (!ns.conn)
+ {
+ crWarning("Failed to connect to host. Make sure 3D acceleration is enabled for this VM.");
+# ifdef VBOXOGL_FAKEDRI
+ return false;
+# else
+ exit(1);
+# endif
+ }
+ else
+ {
+ crNetFreeConnection(ns.conn);
+ }
+ }
+#endif
+
+ strcpy(response, "2 0 feedback 1 pack");
+ spuchain = crStrSplit( response, " " );
+ num_spus = crStrToInt( spuchain[0] );
+ spu_ids = (int *) crAlloc( num_spus * sizeof( *spu_ids ) );
+ spu_names = (char **) crAlloc( num_spus * sizeof( *spu_names ) );
+ for (i = 0 ; i < num_spus ; i++)
+ {
+ spu_ids[i] = crStrToInt( spuchain[2*i+1] );
+ spu_names[i] = crStrdup( spuchain[2*i+2] );
+ crDebug( "SPU %d/%d: (%d) \"%s\"", i+1, num_spus, spu_ids[i], spu_names[i] );
+ }
+
+ stubSetDefaultConfigurationOptions();
+
+#if defined(WINDOWS) && defined(VBOX_WITH_WDDM)
+ hVBoxD3D = NULL;
+ if (!GetModuleHandleEx(0, VBOX_MODNAME_DISPD3D, &hVBoxD3D))
+ {
+ crDebug("GetModuleHandleEx failed err %d", GetLastError());
+ hVBoxD3D = NULL;
+ }
+
+ if (hVBoxD3D)
+ {
+ disable_sync = 1;
+ crDebug("running with %s", VBOX_MODNAME_DISPD3D);
+ stub.trackWindowVisibleRgn = 0;
+ /** @todo should we enable that? */
+ stub.trackWindowSize = 0;
+ stub.trackWindowPos = 0;
+ stub.trackWindowVisibility = 0;
+ stub.bRunningUnderWDDM = true;
+ }
+#endif
+
+ stub.spu = crSPULoadChain( num_spus, spu_ids, spu_names, stub.spu_dir, NULL );
+
+ crFree( spuchain );
+ crFree( spu_ids );
+ for (i = 0; i < num_spus; ++i)
+ crFree(spu_names[i]);
+ crFree( spu_names );
+
+ // spu chain load failed somewhere
+ if (!stub.spu) {
+ return false;
+ }
+
+ crSPUInitDispatchTable( &glim );
+
+ /* This is unlikely to change -- We still want to initialize our dispatch
+ * table with the functions of the first SPU in the chain. */
+ stubInitSPUDispatch( stub.spu );
+
+ /* we need to plug one special stub function into the dispatch table */
+ glim.GetChromiumParametervCR = stub_GetChromiumParametervCR;
+
+#if !defined(VBOX_NO_NATIVEGL)
+ /* Load pointers to native OpenGL functions into stub.nativeDispatch */
+ stubInitNativeDispatch();
+#endif
+
+/*crDebug("stub init");
+raise(SIGINT);*/
+
+#ifdef WINDOWS
+# ifndef CR_NEWWINTRACK
+ stubInstallWindowMessageHook();
+# endif
+#endif
+
+#ifdef CR_NEWWINTRACK
+ {
+ int rc;
+
+ RTR3InitDll(RTR3INIT_FLAGS_UNOBTRUSIVE);
+
+ if (!disable_sync)
+ {
+ crDebug("Starting sync thread");
+
+ rc = RTThreadCreate(&stub.hSyncThread, stubSyncThreadProc, NULL, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "Sync");
+ if (RT_FAILURE(rc))
+ {
+ crError("Failed to start sync thread! (%x)", rc);
+ }
+ RTThreadUserWait(stub.hSyncThread, 60 * 1000);
+ RTThreadUserReset(stub.hSyncThread);
+
+ crDebug("Going on");
+ }
+ }
+#endif
+
+#ifdef GLX
+ stub.xshmSI.shmid = -1;
+ stub.bShmInitFailed = GL_FALSE;
+ stub.pGLXPixmapsHash = crAllocHashtable();
+
+ stub.bXExtensionsChecked = GL_FALSE;
+ stub.bHaveXComposite = GL_FALSE;
+ stub.bHaveXFixes = GL_FALSE;
+#endif
+
+ return true;
+}
+
+/**
+ * Do one-time initializations for the faker.
+ * Returns TRUE on success, FALSE otherwise.
+ */
+bool
+stubInit(void)
+{
+ bool bRc = true;
+ /* we need to serialize the initialization, otherwise racing is possible
+ * for XPDM-based d3d when a d3d switcher is testing the gl lib in two or more threads
+ * NOTE: the STUB_INIT_LOCK/UNLOCK is a NOP for non-win currently */
+ STUB_INIT_LOCK();
+ if (!stub_initialized)
+ bRc = stub_initialized = stubInitLocked();
+ STUB_INIT_UNLOCK();
+ return bRc;
+}
+
+/* Sigh -- we can't do initialization at load time, since Windows forbids
+ * the loading of other libraries from DLLMain. */
+
+#ifdef WINDOWS
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#if 1//def DEBUG_misha
+ /* debugging: this is to be able to catch first-chance notifications
+ * for exceptions other than EXCEPTION_BREAKPOINT in kernel debugger */
+# define VDBG_VEHANDLER
+#endif
+
+#ifdef VDBG_VEHANDLER
+# include <dbghelp.h>
+# include <cr_string.h>
+static PVOID g_VBoxVehHandler = NULL;
+static DWORD g_VBoxVehEnable = 0;
+
+/* generate a crash dump on exception */
+#define VBOXVEH_F_DUMP 0x00000001
+/* generate a debugger breakpoint exception */
+#define VBOXVEH_F_BREAK 0x00000002
+/* exit on exception */
+#define VBOXVEH_F_EXIT 0x00000004
+
+static DWORD g_VBoxVehFlags = 0;
+
+typedef BOOL WINAPI FNVBOXDBG_MINIDUMPWRITEDUMP(HANDLE hProcess,
+ DWORD ProcessId,
+ HANDLE hFile,
+ MINIDUMP_TYPE DumpType,
+ PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
+ PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
+ PMINIDUMP_CALLBACK_INFORMATION CallbackParam);
+typedef FNVBOXDBG_MINIDUMPWRITEDUMP *PFNVBOXDBG_MINIDUMPWRITEDUMP;
+
+static HMODULE g_hVBoxMdDbgHelp = NULL;
+static PFNVBOXDBG_MINIDUMPWRITEDUMP g_pfnVBoxMdMiniDumpWriteDump = NULL;
+static size_t g_cVBoxMdFilePrefixLen = 0;
+static WCHAR g_aszwVBoxMdFilePrefix[MAX_PATH];
+static WCHAR g_aszwVBoxMdDumpCount = 0;
+static MINIDUMP_TYPE g_enmVBoxMdDumpType = MiniDumpNormal
+ | MiniDumpWithDataSegs
+ | MiniDumpWithFullMemory
+ | MiniDumpWithHandleData
+//// | MiniDumpFilterMemory
+//// | MiniDumpScanMemory
+// | MiniDumpWithUnloadedModules
+//// | MiniDumpWithIndirectlyReferencedMemory
+//// | MiniDumpFilterModulePaths
+// | MiniDumpWithProcessThreadData
+// | MiniDumpWithPrivateReadWriteMemory
+//// | MiniDumpWithoutOptionalData
+// | MiniDumpWithFullMemoryInfo
+// | MiniDumpWithThreadInfo
+// | MiniDumpWithCodeSegs
+// | MiniDumpWithFullAuxiliaryState
+// | MiniDumpWithPrivateWriteCopyMemory
+// | MiniDumpIgnoreInaccessibleMemory
+// | MiniDumpWithTokenInformation
+//// | MiniDumpWithModuleHeaders
+//// | MiniDumpFilterTriage
+ ;
+
+
+
+#define VBOXMD_DUMP_DIR_DEFAULT "C:\\dumps"
+#define VBOXMD_DUMP_NAME_PREFIX_W L"VBoxDmp_"
+
+static HMODULE loadSystemDll(const char *pszName)
+{
+#ifndef DEBUG
+ char szPath[MAX_PATH];
+ UINT cchPath = GetSystemDirectoryA(szPath, sizeof(szPath));
+ size_t cbName = strlen(pszName) + 1;
+ if (cchPath + 1 + cbName > sizeof(szPath))
+ {
+ SetLastError(ERROR_FILENAME_EXCED_RANGE);
+ return NULL;
+ }
+ szPath[cchPath] = '\\';
+ memcpy(&szPath[cchPath + 1], pszName, cbName);
+ return LoadLibraryA(szPath);
+#else
+ return LoadLibraryA(pszName);
+#endif
+}
+
+static DWORD vboxMdMinidumpCreate(struct _EXCEPTION_POINTERS *pExceptionInfo)
+{
+ WCHAR aszwMdFileName[MAX_PATH];
+ HANDLE hProcess = GetCurrentProcess();
+ DWORD ProcessId = GetCurrentProcessId();
+ MINIDUMP_EXCEPTION_INFORMATION ExceptionInfo;
+ HANDLE hFile;
+ DWORD winErr = ERROR_SUCCESS;
+
+ if (!g_pfnVBoxMdMiniDumpWriteDump)
+ {
+ if (!g_hVBoxMdDbgHelp)
+ {
+ g_hVBoxMdDbgHelp = loadSystemDll("DbgHelp.dll");
+ if (!g_hVBoxMdDbgHelp)
+ return GetLastError();
+ }
+
+ g_pfnVBoxMdMiniDumpWriteDump = (PFNVBOXDBG_MINIDUMPWRITEDUMP)GetProcAddress(g_hVBoxMdDbgHelp, "MiniDumpWriteDump");
+ if (!g_pfnVBoxMdMiniDumpWriteDump)
+ return GetLastError();
+ }
+
+ ++g_aszwVBoxMdDumpCount;
+
+ memcpy(aszwMdFileName, g_aszwVBoxMdFilePrefix, g_cVBoxMdFilePrefixLen * sizeof (g_aszwVBoxMdFilePrefix[0]));
+ swprintf(aszwMdFileName + g_cVBoxMdFilePrefixLen, RT_ELEMENTS(aszwMdFileName) - g_cVBoxMdFilePrefixLen, L"%d_%d.dmp", ProcessId, g_aszwVBoxMdDumpCount);
+
+ hFile = CreateFileW(aszwMdFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ return GetLastError();
+
+ ExceptionInfo.ThreadId = GetCurrentThreadId();
+ ExceptionInfo.ExceptionPointers = pExceptionInfo;
+ ExceptionInfo.ClientPointers = FALSE;
+
+ if (!g_pfnVBoxMdMiniDumpWriteDump(hProcess, ProcessId, hFile, g_enmVBoxMdDumpType, &ExceptionInfo, NULL, NULL))
+ winErr = GetLastError();
+
+ CloseHandle(hFile);
+ return winErr;
+}
+
+LONG WINAPI vboxVDbgVectoredHandler(struct _EXCEPTION_POINTERS *pExceptionInfo)
+{
+ PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord;
+ PCONTEXT pContextRecord = pExceptionInfo->ContextRecord;
+ switch (pExceptionRecord->ExceptionCode)
+ {
+ case EXCEPTION_BREAKPOINT:
+ case EXCEPTION_ACCESS_VIOLATION:
+ case EXCEPTION_STACK_OVERFLOW:
+ case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
+ case EXCEPTION_FLT_DIVIDE_BY_ZERO:
+ case EXCEPTION_FLT_INVALID_OPERATION:
+ case EXCEPTION_INT_DIVIDE_BY_ZERO:
+ case EXCEPTION_ILLEGAL_INSTRUCTION:
+ if (g_VBoxVehFlags & VBOXVEH_F_BREAK)
+ {
+ BOOL fBreak = TRUE;
+#ifndef DEBUG_misha
+ if (pExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT)
+ {
+ HANDLE hProcess = GetCurrentProcess();
+ BOOL fDebuggerPresent = FALSE;
+ /* we do not want to generate breakpoint exceptions recursively, so do it only when running under debugger */
+ if (CheckRemoteDebuggerPresent(hProcess, &fDebuggerPresent))
+ fBreak = !!fDebuggerPresent;
+ else
+ fBreak = FALSE; /* <- the function has failed, don't break for sanity */
+ }
+#endif
+
+ if (fBreak)
+ {
+ RT_BREAKPOINT();
+ }
+ }
+
+ if (g_VBoxVehFlags & VBOXVEH_F_DUMP)
+ vboxMdMinidumpCreate(pExceptionInfo);
+
+ if (g_VBoxVehFlags & VBOXVEH_F_EXIT)
+ exit(1);
+ break;
+ default:
+ break;
+ }
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+
+void vboxVDbgVEHandlerRegister()
+{
+ CRASSERT(!g_VBoxVehHandler);
+ g_VBoxVehHandler = AddVectoredExceptionHandler(1,vboxVDbgVectoredHandler);
+ CRASSERT(g_VBoxVehHandler);
+}
+
+void vboxVDbgVEHandlerUnregister()
+{
+ ULONG uResult;
+ if (g_VBoxVehHandler)
+ {
+ uResult = RemoveVectoredExceptionHandler(g_VBoxVehHandler);
+ CRASSERT(uResult);
+ g_VBoxVehHandler = NULL;
+ }
+}
+#endif
+
+/* Windows crap */
+BOOL WINAPI DllMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved)
+{
+ (void) lpvReserved;
+
+ switch (fdwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ {
+ CRNetServer ns;
+ const char * env;
+#if defined(DEBUG_misha)
+ HMODULE hCrUtil;
+ char aName[MAX_PATH];
+
+ GetModuleFileNameA(hDLLInst, aName, RT_ELEMENTS(aName));
+ crDbgCmdSymLoadPrint(aName, hDLLInst);
+
+ hCrUtil = GetModuleHandleA("VBoxOGLcrutil.dll");
+ Assert(hCrUtil);
+ crDbgCmdSymLoadPrint("VBoxOGLcrutil.dll", hCrUtil);
+#endif
+#ifdef CHROMIUM_THREADSAFE
+ crInitTSD(&g_stubCurrentContextTSD);
+#endif
+
+ crInitMutex(&stub_init_mutex);
+
+#ifdef VDBG_VEHANDLER
+ env = crGetenv("CR_DBG_VEH_ENABLE");
+ g_VBoxVehEnable = crStrParseI32(env,
+# ifdef DEBUG_misha
+ 1
+# else
+ 0
+# endif
+ );
+
+ if (g_VBoxVehEnable)
+ {
+ char procName[1024];
+ size_t cProcName;
+ size_t cChars;
+
+ env = crGetenv("CR_DBG_VEH_FLAGS");
+ g_VBoxVehFlags = crStrParseI32(env,
+ 0
+# ifdef DEBUG_misha
+ | VBOXVEH_F_BREAK
+# else
+ | VBOXVEH_F_DUMP
+# endif
+ );
+
+ env = crGetenv("CR_DBG_VEH_DUMP_DIR");
+ if (!env)
+ env = VBOXMD_DUMP_DIR_DEFAULT;
+
+ g_cVBoxMdFilePrefixLen = strlen(env);
+
+ if (RT_ELEMENTS(g_aszwVBoxMdFilePrefix) <= g_cVBoxMdFilePrefixLen + 26 + (sizeof (VBOXMD_DUMP_NAME_PREFIX_W) - sizeof (WCHAR)) / sizeof (WCHAR))
+ {
+ g_cVBoxMdFilePrefixLen = 0;
+ env = "";
+ }
+
+ mbstowcs_s(&cChars, g_aszwVBoxMdFilePrefix, g_cVBoxMdFilePrefixLen + 1, env, _TRUNCATE);
+
+ Assert(cChars == g_cVBoxMdFilePrefixLen + 1);
+
+ g_cVBoxMdFilePrefixLen = cChars - 1;
+
+ if (g_cVBoxMdFilePrefixLen && g_aszwVBoxMdFilePrefix[g_cVBoxMdFilePrefixLen - 1] != L'\\')
+ g_aszwVBoxMdFilePrefix[g_cVBoxMdFilePrefixLen++] = L'\\';
+
+ memcpy(g_aszwVBoxMdFilePrefix + g_cVBoxMdFilePrefixLen, VBOXMD_DUMP_NAME_PREFIX_W, sizeof (VBOXMD_DUMP_NAME_PREFIX_W) - sizeof (WCHAR));
+ g_cVBoxMdFilePrefixLen += (sizeof (VBOXMD_DUMP_NAME_PREFIX_W) - sizeof (WCHAR)) / sizeof (WCHAR);
+
+ crGetProcName(procName, RT_ELEMENTS(procName));
+ cProcName = strlen(procName);
+
+ if (RT_ELEMENTS(g_aszwVBoxMdFilePrefix) > g_cVBoxMdFilePrefixLen + cProcName + 1 + 26)
+ {
+ mbstowcs_s(&cChars, g_aszwVBoxMdFilePrefix + g_cVBoxMdFilePrefixLen, cProcName + 1, procName, _TRUNCATE);
+ Assert(cChars == cProcName + 1);
+ g_cVBoxMdFilePrefixLen += cChars - 1;
+ g_aszwVBoxMdFilePrefix[g_cVBoxMdFilePrefixLen++] = L'_';
+ }
+
+ /* sanity */
+ g_aszwVBoxMdFilePrefix[g_cVBoxMdFilePrefixLen] = L'\0';
+
+ env = crGetenv("CR_DBG_VEH_DUMP_TYPE");
+
+ g_enmVBoxMdDumpType = crStrParseI32(env,
+ MiniDumpNormal
+ | MiniDumpWithDataSegs
+ | MiniDumpWithFullMemory
+ | MiniDumpWithHandleData
+ //// | MiniDumpFilterMemory
+ //// | MiniDumpScanMemory
+ // | MiniDumpWithUnloadedModules
+ //// | MiniDumpWithIndirectlyReferencedMemory
+ //// | MiniDumpFilterModulePaths
+ // | MiniDumpWithProcessThreadData
+ // | MiniDumpWithPrivateReadWriteMemory
+ //// | MiniDumpWithoutOptionalData
+ // | MiniDumpWithFullMemoryInfo
+ // | MiniDumpWithThreadInfo
+ // | MiniDumpWithCodeSegs
+ // | MiniDumpWithFullAuxiliaryState
+ // | MiniDumpWithPrivateWriteCopyMemory
+ // | MiniDumpIgnoreInaccessibleMemory
+ // | MiniDumpWithTokenInformation
+ //// | MiniDumpWithModuleHeaders
+ //// | MiniDumpFilterTriage
+ );
+
+ vboxVDbgVEHandlerRegister();
+ }
+#endif
+
+ crNetInit(NULL, NULL);
+ ns.name = "vboxhgcm://host:0";
+ ns.buffer_size = 1024;
+ crNetServerConnect(&ns
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , NULL
+#endif
+);
+ if (!ns.conn)
+ {
+ crDebug("Failed to connect to host (is guest 3d acceleration enabled?), aborting ICD load.");
+#ifdef VDBG_VEHANDLER
+ if (g_VBoxVehEnable)
+ vboxVDbgVEHandlerUnregister();
+#endif
+ return FALSE;
+ }
+ else
+ {
+ crNetFreeConnection(ns.conn);
+ }
+
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ VBoxCrHgsmiInit();
+#endif
+ break;
+ }
+
+ case DLL_PROCESS_DETACH:
+ {
+ /* do exactly the same thing as for DLL_THREAD_DETACH since
+ * DLL_THREAD_DETACH is not called for the thread doing DLL_PROCESS_DETACH according to msdn docs */
+ stubSetCurrentContext(NULL);
+ if (stub_initialized)
+ {
+ CRASSERT(stub.spu);
+ stub.spu->dispatch_table.VBoxDetachThread();
+ }
+
+
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ VBoxCrHgsmiTerm();
+#endif
+
+ stubSPUSafeTearDown();
+
+#ifdef CHROMIUM_THREADSAFE
+ crFreeTSD(&g_stubCurrentContextTSD);
+#endif
+
+#ifdef VDBG_VEHANDLER
+ if (g_VBoxVehEnable)
+ vboxVDbgVEHandlerUnregister();
+#endif
+ break;
+ }
+
+ case DLL_THREAD_ATTACH:
+ {
+ if (stub_initialized)
+ {
+ CRASSERT(stub.spu);
+ stub.spu->dispatch_table.VBoxAttachThread();
+ }
+ break;
+ }
+
+ case DLL_THREAD_DETACH:
+ {
+ stubSetCurrentContext(NULL);
+ if (stub_initialized)
+ {
+ CRASSERT(stub.spu);
+ stub.spu->dispatch_table.VBoxDetachThread();
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+#endif
diff --git a/src/VBox/Additions/common/crOpenGL/pack/Makefile.kup b/src/VBox/Additions/common/crOpenGL/pack/Makefile.kup
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/Makefile.kup
diff --git a/src/VBox/Additions/common/crOpenGL/pack/pack.def b/src/VBox/Additions/common/crOpenGL/pack/pack.def
new file mode 100644
index 00000000..9edc7163
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/pack.def
@@ -0,0 +1,6 @@
+; Copyright (c) 2001, Stanford University
+; All rights reserved.
+;
+; See the file LICENSE.txt for information on redistributing this software.
+EXPORTS
+SPULoad
diff --git a/src/VBox/Additions/common/crOpenGL/pack/pack.py b/src/VBox/Additions/common/crOpenGL/pack/pack.py
new file mode 100755
index 00000000..e25066be
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/pack.py
@@ -0,0 +1,57 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+
+keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+
+apiutil.CopyrightC()
+
+print("""
+/* DO NOT EDIT - THIS FILE AUTOMATICALLY GENERATED BY pack.py SCRIPT */
+#include <stdio.h>
+#include "cr_string.h"
+#include "cr_spu.h"
+#include "packspu.h"
+#include "cr_packfunctions.h"
+#include "packspu_proto.h"
+""")
+
+num_funcs = len(keys) - len(apiutil.AllSpecials('packspu_unimplemented'))
+print('SPUNamedFunctionTable _cr_pack_table[%d];' % (num_funcs+1))
+
+print("""
+static void __fillin(int offset, char *name, SPUGenericFunction func)
+{
+ _cr_pack_table[offset].name = crStrdup(name);
+ _cr_pack_table[offset].fn = func;
+}""")
+
+pack_specials = []
+
+for func_name in keys:
+ if ("get" in apiutil.Properties(func_name) or
+ apiutil.FindSpecial( "packspu", func_name ) or
+ apiutil.FindSpecial( "packspu_flush", func_name ) or
+ apiutil.FindSpecial( "packspu_vertex", func_name )):
+ pack_specials.append( func_name )
+
+print('\nvoid packspuCreateFunctions( void )')
+print('{')
+for index in range(len(keys)):
+ func_name = keys[index]
+ if apiutil.FindSpecial( "packspu_unimplemented", func_name ):
+ continue
+ if func_name in pack_specials:
+ print('\t__fillin(%3d, "%s", (SPUGenericFunction) packspu_%s);' % (index, func_name, func_name ))
+ else:
+ print('\t__fillin(%3d, "%s", (SPUGenericFunction) (pack_spu.swap ? crPack%sSWAP : crPack%s));' % (index, func_name, func_name, func_name ))
+print('\t__fillin(%3d, NULL, NULL);' % num_funcs)
+print('}')
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu.h b/src/VBox/Additions/common/crOpenGL/pack/packspu.h
new file mode 100644
index 00000000..9774e35b
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu.h
@@ -0,0 +1,185 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved.
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#ifndef GA_INCLUDED_SRC_common_crOpenGL_pack_packspu_h
+#define GA_INCLUDED_SRC_common_crOpenGL_pack_packspu_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#ifdef WINDOWS
+#define PACKSPU_APIENTRY __stdcall
+#else
+#define PACKSPU_APIENTRY
+#endif
+
+#include "cr_glstate.h"
+#include "cr_netserver.h"
+#include "cr_pack.h"
+#include "cr_spu.h"
+#include "cr_threads.h"
+#include "state/cr_client.h"
+#ifdef VBOX_WITH_CRPACKSPU_DUMPER
+# include "cr_dump.h"
+#endif
+
+extern uint32_t g_u32VBoxHostCaps;
+
+typedef struct thread_info_t ThreadInfo;
+typedef struct context_info_t ContextInfo;
+typedef struct zvabuffer_info_t ZvaBufferInfo;
+
+struct zvabuffer_info_t
+{
+ /* GL_ARRAY_BUFFER_ARB buffer */
+ GLuint idBuffer;
+ /* buffer length */
+ GLuint cbBuffer;
+ /* number of values stored in the buffer currently */
+ GLuint cValues;
+ /* current buffer value */
+ union
+ {
+ GLfloat f[4];
+ GLuint ui[4];
+ GLubyte ub[4];
+ GLshort s[4];
+ GLushort us[4];
+ } Value;
+};
+
+struct thread_info_t {
+ unsigned long id;
+ CRNetServer netServer;
+ CRPackBuffer buffer;
+ CRPackBuffer normBuffer;
+ CRPackBuffer BeginEndBuffer;
+ GLenum BeginEndMode;
+ int BeginEndState;
+ ContextInfo *currentContext;
+ CRPackContext *packer;
+ int writeback;
+ GLboolean bInjectThread;
+ GLboolean inUse;
+};
+
+struct context_info_t {
+ CRContext *clientState; /* used to store client-side GL state */
+ GLint serverCtx; /* context ID returned by server */
+ GLboolean fAutoFlush;
+ GLboolean fCheckZerroVertAttr;
+ ThreadInfo *currentThread;
+ ZvaBufferInfo zvaBufferInfo;
+ GLubyte glVersion[100]; /* GL_VERSION string */
+ GLubyte pszRealVendor[100];
+ GLubyte pszRealVersion[100];
+ GLubyte pszRealRenderer[100];
+};
+
+typedef struct {
+ int id;
+ int swap;
+
+ /* config options */
+ int emit_GATHER_POST_SWAPBUFFERS;
+ int swapbuffer_sync;
+
+ int ReadPixels;
+
+ char *name;
+ int buffer_size;
+
+ int numThreads; /*number of used threads in the next array, doesn't need to be cont*/
+ ThreadInfo thread[MAX_THREADS];
+ int idxThreadInUse; /*index of any used thread*/
+
+#if defined(WINDOWS) && defined(VBOX_WITH_WDDM)
+ bool bIsWDDMCrHgsmi;
+#endif
+
+ SPUDispatchTable self;
+
+#ifdef VBOX_WITH_CRPACKSPU_DUMPER
+ CR_RECORDER Recorder;
+ CR_DBGPRINT_DUMPER Dumper;
+#endif
+
+ int numContexts;
+ ContextInfo context[CR_MAX_CONTEXTS];
+} PackSPU;
+
+extern PackSPU pack_spu;
+
+#define THREAD_OFFSET_MAGIC 2000
+
+#ifdef CHROMIUM_THREADSAFE
+extern CRmutex _PackMutex;
+extern CRtsd _PackTSD;
+#define GET_THREAD_VAL() (crGetTSD(&_PackTSD))
+#define GET_THREAD_IDX(_id) ((_id) - THREAD_OFFSET_MAGIC)
+#define GET_THREAD_VAL_ID(_id) (&(pack_spu.thread[GET_THREAD_IDX(_id)]))
+#else
+#define GET_THREAD_VAL() (&(pack_spu.thread[0]))
+#endif
+#define GET_THREAD(T) ThreadInfo *T = GET_THREAD_VAL()
+#define GET_THREAD_ID(T, _id) ThreadInfo *T = GET_THREAD_VAL_ID(_id)
+
+
+
+#define GET_CONTEXT(C) \
+ GET_THREAD(thread); \
+ ContextInfo *C = thread->currentContext
+
+#ifdef DEBUG_misha
+# define CRPACKSPU_WRITEBACK_ASSERT_ZERO(_writeback) Assert(!(_writeback))
+#else
+# define CRPACKSPU_WRITEBACK_ASSERT_ZERO(_writeback) do {} while (0)
+#endif
+
+#define CRPACKSPU_WRITEBACK_WAIT(_thread, _writeback) do {\
+ if (g_u32VBoxHostCaps & CR_VBOX_CAP_CMDVBVA) { \
+ CRPACKSPU_WRITEBACK_ASSERT_ZERO(_writeback); \
+ (_writeback) = 0; \
+ break; \
+ } \
+ CR_WRITEBACK_WAIT((_thread)->netServer.conn, _writeback); \
+ } while (0)
+
+#if defined(WINDOWS) && defined(VBOX_WITH_WDDM) && defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+# define CRPACKSPU_IS_WDDM_CRHGSMI() (pack_spu.bIsWDDMCrHgsmi)
+#else
+# define CRPACKSPU_IS_WDDM_CRHGSMI() (GL_FALSE)
+#endif
+
+extern void packspuCreateFunctions( void );
+extern void packspuSetVBoxConfiguration( const SPU *child_spu );
+extern void packspuConnectToServer( CRNetServer *server
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , struct VBOXUHGSMI *pHgsmi
+#endif
+ );
+extern void packspuFlush( void *arg );
+extern void packspuHuge( CROpcode opcode, void *buf );
+
+extern void packspuInitStrings(void);
+
+extern GLboolean packspuSyncOnFlushes(void);
+
+extern ThreadInfo *packspuNewThread(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ struct VBOXUHGSMI *pHgsmi
+#else
+ void
+#endif
+ );
+
+extern ThreadInfo *packspuNewCtxThread( struct VBOXUHGSMI *pHgsmi );
+
+
+
+#define MAGIC_OFFSET 3000
+
+#endif /* !GA_INCLUDED_SRC_common_crOpenGL_pack_packspu_h */
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu.rc b/src/VBox/Additions/common/crOpenGL/pack/packspu.rc
new file mode 100644
index 00000000..b120f236
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu.rc
@@ -0,0 +1,69 @@
+/* $Id: packspu.rc $ */
+/** @file
+ * VBoxOGLpackspu - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2009-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_RC_FILE_VERSION
+ PRODUCTVERSION VBOX_RC_FILE_VERSION
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS VBOX_RC_FILE_FLAGS
+ FILEOS VBOX_RC_FILE_OS
+ FILETYPE VBOX_RC_TYPE_DRV
+ FILESUBTYPE VFT2_DRV_DISPLAY
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "VirtualBox crOpenGL ICD\0"
+ VALUE "InternalName", "VBoxOGLpackspu\0"
+#ifdef VBOX_WDDM_WOW64
+ VALUE "OriginalFilename", "VBoxOGLpackspu-x86.dll\0"
+#else
+ VALUE "OriginalFilename", "VBoxOGLpackspu.dll\0"
+#endif
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileVersion", VBOX_RC_FILE_VERSION_STR
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "ProductName", VBOX_RC_PRODUCT_NAME_GA_STR
+ VALUE "ProductVersion", VBOX_RC_PRODUCT_VERSION_STR
+ VBOX_RC_MORE_STRINGS
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+1 RCDATA
+BEGIN
+// Machine dependent parameters
+ 17, // Height of vertical thumb
+ 17, // Width of horizontal thumb
+ 2, // Icon horiz compression factor
+ 2, // Icon vert compression factor
+ 1, // Cursor horz compression factor
+ 1, // Cursor vert compression factor
+ 0, // Kanji window height
+ 1, // cxBorder (thickness of vertical lines)
+ 1 // cyBorder (thickness of horizontal lines)
+END
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_beginend.py b/src/VBox/Additions/common/crOpenGL/pack/packspu_beginend.py
new file mode 100755
index 00000000..2195cab5
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_beginend.py
@@ -0,0 +1,177 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+
+apiutil.CopyrightC()
+
+print("""/* DO NOT EDIT - AUTOMATICALLY GENERATED BY packspu_beginend.py */
+#include "packspu.h"
+#include "assert.h"
+#include "cr_packfunctions.h"
+#include "packspu_proto.h"
+
+void PACKSPU_APIENTRY packspu_Begin( GLenum mode )
+{
+ CRPackBuffer *buf;
+#if CR_ARB_vertex_buffer_object
+ GET_CONTEXT(ctx);
+#else
+ GET_THREAD(thread);
+#endif
+
+ buf = &thread->BeginEndBuffer;
+
+ /* XXX comparing mode >= 0 here is not needed since mode is unsigned */
+ CRASSERT( /*mode >= GL_POINTS && */mode <= GL_POLYGON );
+
+#if CR_ARB_vertex_buffer_object
+ {
+ GLboolean serverArrays = GL_FALSE;
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object)
+ serverArrays = crStateUseServerArrays();
+ if (serverArrays) {
+ CRClientState *clientState = &(ctx->clientState->client);
+ if (clientState->array.locked && !clientState->array.synced)
+ {
+ crPackLockArraysEXT(clientState->array.lockFirst, clientState->array.lockCount);
+ clientState->array.synced = GL_TRUE;
+ }
+ }
+ }
+#endif
+
+ if (pack_spu.swap)
+ {
+ crPackBeginSWAP( mode );
+ }
+ else
+ {
+ crPackBegin( mode );
+ }
+
+ if ( thread->netServer.conn->Barf ) {
+ thread->BeginEndMode = mode;
+ thread->BeginEndState = -1;
+ if ( mode == GL_LINES || mode == GL_TRIANGLES || mode == GL_QUADS || mode == GL_POLYGON )
+ {
+ CRASSERT(!buf->pack);
+
+ crPackReleaseBuffer( thread->packer );
+ buf->pack = crNetAlloc( thread->netServer.conn );
+ crPackInitBuffer( buf, buf->pack, thread->netServer.conn->buffer_size, thread->netServer.conn->mtu );
+ buf->holds_BeginEnd = 1;
+ buf->in_BeginEnd = 1;
+ crPackSetBuffer( thread->packer, buf );
+
+ thread->BeginEndState = 0;
+ }
+ }
+}
+
+void PACKSPU_APIENTRY packspu_End( void )
+{
+ GET_THREAD(thread);
+ CRPackBuffer *buf = &thread->BeginEndBuffer;
+
+ if ( thread->netServer.conn->Barf &&
+ (thread->BeginEndMode == GL_LINES
+ || thread->BeginEndMode == GL_TRIANGLES
+ || thread->BeginEndMode == GL_QUADS
+ || thread->BeginEndMode == GL_POLYGON ) )
+ {
+ CRASSERT(buf->pack);
+
+ crPackReleaseBuffer( thread->packer );
+ crPackSetBuffer( thread->packer, &thread->normBuffer );
+ if ( !crPackCanHoldBuffer( buf ) )
+ packspuFlush( (void *) thread );
+
+ crPackAppendBuffer( buf );
+ crNetFree( thread->netServer.conn, buf->pack );
+ buf->pack = NULL;
+ }
+
+ if (pack_spu.swap)
+ {
+ crPackEndSWAP();
+ }
+ else
+ {
+ crPackEnd();
+ }
+}
+
+static void DoVertex( void )
+{
+ GET_THREAD(thread);
+ CRPackBuffer *buf = &thread->BeginEndBuffer;
+ CRPackBuffer *gbuf = &thread->normBuffer;
+ int num_data;
+ int num_opcode;
+
+ /*crDebug( "really doing Vertex" );*/
+ crPackReleaseBuffer( thread->packer );
+ num_data = buf->data_current - buf->data_start;
+ num_opcode = buf->opcode_start - buf->opcode_current;
+ crPackSetBuffer( thread->packer, gbuf );
+ if ( !crPackCanHoldBuffer( buf ) )
+ /* doesn't hold, first flush gbuf*/
+ packspuFlush( (void *) thread );
+
+ crPackAppendBuffer( buf );
+ crPackReleaseBuffer( thread->packer );
+ crPackSetBuffer( thread->packer, buf );
+ crPackResetPointers(thread->packer);
+}
+
+static void RunState( void )
+{
+ GET_THREAD(thread);
+ if (! thread->netServer.conn->Barf ) return;
+ if (thread->BeginEndState == -1) return;
+ switch(thread->BeginEndMode) {
+ case GL_POLYGON:
+ return;
+ case GL_LINES:
+ thread->BeginEndState = (thread->BeginEndState + 1) % 2;
+ if (thread->BeginEndState)
+ return;
+ break;
+ case GL_TRIANGLES:
+ thread->BeginEndState = (thread->BeginEndState + 1) % 3;
+ if (thread->BeginEndState)
+ return;
+ break;
+ case GL_QUADS:
+ thread->BeginEndState = (thread->BeginEndState + 1) % 4;
+ if (thread->BeginEndState)
+ return;
+ break;
+ }
+ DoVertex();
+}
+""")
+
+keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+for func_name in apiutil.AllSpecials( "packspu_vertex" ):
+ params = apiutil.Parameters(func_name)
+ print('void PACKSPU_APIENTRY packspu_%s(%s)' % ( func_name, apiutil.MakeDeclarationString(params) ))
+ print('{')
+ print('\tif (pack_spu.swap)')
+ print('\t{')
+ print('\t\tcrPack%sSWAP(%s);' % ( func_name, apiutil.MakeCallString( params ) ))
+ print('\t}')
+ print('\telse')
+ print('\t{')
+ print('\t\tcrPack%s(%s);' % ( func_name, apiutil.MakeCallString( params ) ))
+ print('\t}')
+ print('\tRunState();')
+ print('}')
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_bufferobject.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_bufferobject.c
new file mode 100644
index 00000000..65f64bd7
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_bufferobject.c
@@ -0,0 +1,160 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "cr_error.h"
+#include "cr_mem.h"
+#include "cr_string.h"
+#include "packspu.h"
+#include "packspu_proto.h"
+
+static void packspu_GetHostBufferSubDataARB( GLenum target, GLintptrARB offset, GLsizeiptrARB size, void * data )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+
+ crPackGetBufferSubDataARB(target, offset, size, data, &writeback);
+
+ packspuFlush((void *) thread);
+
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+}
+
+void * PACKSPU_APIENTRY
+packspu_MapBufferARB( GLenum target, GLenum access )
+{
+ GET_CONTEXT(ctx);
+ void *buffer;
+ CRBufferObject *pBufObj;
+
+ CRASSERT(GL_TRUE == ctx->clientState->bufferobject.retainBufferData);
+ buffer = crStateMapBufferARB(target, access);
+
+#ifdef CR_ARB_pixel_buffer_object
+ if (buffer)
+ {
+ pBufObj = crStateGetBoundBufferObject(target, &ctx->clientState->bufferobject);
+ CRASSERT(pBufObj);
+
+ if (pBufObj->bResyncOnRead &&
+ access != GL_WRITE_ONLY_ARB)
+ {
+ /*fetch data from host side*/
+ packspu_GetHostBufferSubDataARB(target, 0, pBufObj->size, buffer);
+ }
+ }
+#endif
+
+ return buffer;
+}
+
+void PACKSPU_APIENTRY packspu_GetBufferSubDataARB( GLenum target, GLintptrARB offset, GLsizeiptrARB size, void * data )
+{
+ GET_CONTEXT(ctx);
+
+#ifdef CR_ARB_pixel_buffer_object
+ CRBufferObject *pBufObj;
+
+ pBufObj = crStateGetBoundBufferObject(target, &ctx->clientState->bufferobject);
+
+ if (pBufObj && pBufObj->bResyncOnRead)
+ {
+ packspu_GetHostBufferSubDataARB(target, offset, size, data);
+ return;
+ }
+#endif
+
+ crStateGetBufferSubDataARB(target, offset, size, data);
+}
+
+
+GLboolean PACKSPU_APIENTRY
+packspu_UnmapBufferARB( GLenum target )
+{
+ GET_CONTEXT(ctx);
+
+#if CR_ARB_vertex_buffer_object
+ CRBufferObject *bufObj;
+
+ bufObj = crStateGetBoundBufferObject(target, &ctx->clientState->bufferobject);
+
+ /* send new buffer contents to server */
+ crPackBufferDataARB( target, bufObj->size, bufObj->pointer, bufObj->usage );
+#endif
+
+ CRASSERT(GL_TRUE == ctx->clientState->bufferobject.retainBufferData);
+ crStateUnmapBufferARB( target );
+
+ return GL_TRUE;
+}
+
+
+void PACKSPU_APIENTRY
+packspu_BufferDataARB(GLenum target, GLsizeiptrARB size, const GLvoid * data, GLenum usage)
+{
+ /*crDebug("packspu_BufferDataARB size:%d", size);*/
+ crStateBufferDataARB(target, size, data, usage);
+ crPackBufferDataARB(target, size, data, usage);
+}
+
+void PACKSPU_APIENTRY
+packspu_BufferSubDataARB(GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid * data)
+{
+ /*crDebug("packspu_BufferSubDataARB size:%d", size);*/
+ crStateBufferSubDataARB(target, offset, size, data);
+ crPackBufferSubDataARB(target, offset, size, data);
+}
+
+
+void PACKSPU_APIENTRY
+packspu_GetBufferPointervARB(GLenum target, GLenum pname, GLvoid **params)
+{
+ crStateGetBufferPointervARB( target, pname, params );
+}
+
+
+void PACKSPU_APIENTRY
+packspu_GetBufferParameterivARB( GLenum target, GLenum pname, GLint * params )
+{
+ crStateGetBufferParameterivARB( target, pname, params );
+}
+
+/*
+ * Need to update our local state for vertex arrays.
+ */
+void PACKSPU_APIENTRY
+packspu_BindBufferARB( GLenum target, GLuint buffer )
+{
+ crStateBindBufferARB(target, buffer);
+ crPackBindBufferARB(target, buffer);
+}
+
+void PACKSPU_APIENTRY packspu_GenBuffersARB( GLsizei n, GLuint * buffer )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI() && !(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
+ {
+ crError( "packspu_GenBuffersARB doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!" );
+ }
+ if (pack_spu.swap)
+ {
+ crPackGenBuffersARBSWAP( n, buffer, &writeback );
+ }
+ else
+ {
+ crPackGenBuffersARB( n, buffer, &writeback );
+ }
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ crStateRegBuffers(n, buffer);
+}
+
+void PACKSPU_APIENTRY packspu_DeleteBuffersARB( GLsizei n, const GLuint * buffer )
+{
+ crStateDeleteBuffersARB( n, buffer );
+ crPackDeleteBuffersARB(n, buffer);
+}
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_client.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_client.c
new file mode 100644
index 00000000..19c11880
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_client.c
@@ -0,0 +1,910 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "packspu.h"
+#include "cr_packfunctions.h"
+#include "cr_glstate.h"
+#include "packspu_proto.h"
+#include "cr_mem.h"
+
+void PACKSPU_APIENTRY packspu_FogCoordPointerEXT( GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+#if CR_ARB_vertex_buffer_object
+ GET_CONTEXT(ctx);
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
+ if (pack_spu.swap)
+ crPackFogCoordPointerEXTSWAP( type, stride, pointer );
+ else
+ crPackFogCoordPointerEXT( type, stride, pointer );
+ }
+#endif
+ crStateFogCoordPointerEXT( type, stride, pointer );
+}
+
+void PACKSPU_APIENTRY packspu_ColorPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+#if CR_ARB_vertex_buffer_object
+ GET_CONTEXT(ctx);
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
+ if (pack_spu.swap)
+ crPackColorPointerSWAP( size, type, stride, pointer );
+ else
+ crPackColorPointer( size, type, stride, pointer );
+ }
+#endif
+ crStateColorPointer( size, type, stride, pointer );
+}
+
+void PACKSPU_APIENTRY packspu_SecondaryColorPointerEXT( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+#if CR_ARB_vertex_buffer_object
+ GET_CONTEXT(ctx);
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
+ if (pack_spu.swap)
+ crPackSecondaryColorPointerEXTSWAP( size, type, stride, pointer );
+ else
+ crPackSecondaryColorPointerEXT( size, type, stride, pointer );
+ }
+#endif
+ crStateSecondaryColorPointerEXT( size, type, stride, pointer );
+}
+
+void PACKSPU_APIENTRY packspu_VertexPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+#if CR_ARB_vertex_buffer_object
+ GET_CONTEXT(ctx);
+ CRASSERT(ctx->clientState->extensions.ARB_vertex_buffer_object);
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
+ if (pack_spu.swap)
+ crPackVertexPointerSWAP( size, type, stride, pointer );
+ else
+ crPackVertexPointer( size, type, stride, pointer );
+ }
+#endif
+ crStateVertexPointer( size, type, stride, pointer );
+}
+
+void PACKSPU_APIENTRY packspu_TexCoordPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+#if CR_ARB_vertex_buffer_object
+ GET_CONTEXT(ctx);
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
+ if (pack_spu.swap)
+ crPackTexCoordPointerSWAP( size, type, stride, pointer );
+ else
+ crPackTexCoordPointer( size, type, stride, pointer );
+ }
+#endif
+ crStateTexCoordPointer( size, type, stride, pointer );
+}
+
+void PACKSPU_APIENTRY packspu_NormalPointer( GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+#if CR_ARB_vertex_buffer_object
+ GET_CONTEXT(ctx);
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
+ if (pack_spu.swap)
+ crPackNormalPointerSWAP( type, stride, pointer );
+ else
+ crPackNormalPointer( type, stride, pointer );
+ }
+#endif
+ crStateNormalPointer( type, stride, pointer );
+}
+
+void PACKSPU_APIENTRY packspu_EdgeFlagPointer( GLsizei stride, const GLvoid *pointer )
+{
+#if CR_ARB_vertex_buffer_object
+ GET_CONTEXT(ctx);
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
+ if (pack_spu.swap)
+ crPackEdgeFlagPointerSWAP( stride, pointer );
+ else
+ crPackEdgeFlagPointer( stride, pointer );
+ }
+#endif
+ crStateEdgeFlagPointer( stride, pointer );
+}
+
+void PACKSPU_APIENTRY packspu_VertexAttribPointerARB( GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer )
+{
+#if CR_ARB_vertex_buffer_object
+ GET_CONTEXT(ctx);
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
+ if (pack_spu.swap)
+ crPackVertexAttribPointerARBSWAP( index, size, type, normalized, stride, pointer );
+ else
+ crPackVertexAttribPointerARB( index, size, type, normalized, stride, pointer );
+ }
+#endif
+ crStateVertexAttribPointerARB( index, size, type, normalized, stride, pointer );
+}
+
+void PACKSPU_APIENTRY packspu_VertexAttribPointerNV( GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+#if CR_ARB_vertex_buffer_object
+ GET_CONTEXT(ctx);
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
+ if (pack_spu.swap)
+ crPackVertexAttribPointerNVSWAP( index, size, type, stride, pointer );
+ else
+ crPackVertexAttribPointerNV( index, size, type, stride, pointer );
+ }
+#endif
+ crStateVertexAttribPointerNV( index, size, type, stride, pointer );
+}
+
+void PACKSPU_APIENTRY packspu_IndexPointer( GLenum type, GLsizei stride, const GLvoid *pointer )
+{
+#if CR_ARB_vertex_buffer_object
+ GET_CONTEXT(ctx);
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
+ if (pack_spu.swap)
+ crPackIndexPointerSWAP( type, stride, pointer );
+ else
+ crPackIndexPointer( type, stride, pointer );
+ }
+#endif
+ crStateIndexPointer(type, stride, pointer);
+}
+
+void PACKSPU_APIENTRY packspu_GetPointerv( GLenum pname, GLvoid **params )
+{
+ crStateGetPointerv( pname, params );
+}
+
+void PACKSPU_APIENTRY packspu_InterleavedArrays( GLenum format, GLsizei stride, const GLvoid *pointer )
+{
+#if CR_ARB_vertex_buffer_object
+ GET_CONTEXT(ctx);
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object) {
+ if (pack_spu.swap)
+ crPackInterleavedArraysSWAP( format, stride, pointer );
+ else
+ crPackInterleavedArrays( format, stride, pointer );
+ }
+#endif
+
+ /*crDebug("packspu_InterleavedArrays");*/
+
+ crStateInterleavedArrays( format, stride, pointer );
+}
+
+#ifdef DEBUG_misha
+/* debugging */
+//# define CR_FORCE_ZVA_SERVER_ARRAY
+#endif
+# define CR_FORCE_ZVA_EXPAND
+
+
+static GLboolean packspuZvaCreate(ContextInfo *pCtx, const GLfloat *pValue, GLuint cValues)
+{
+ ZvaBufferInfo *pInfo = &pCtx->zvaBufferInfo;
+ GLuint cbValue = 4 * sizeof (*pValue);
+ GLuint cbValues = cValues * cbValue;
+ GLfloat *pBuffer;
+ uint8_t *pu8Buf;
+ GLuint i;
+
+ /* quickly sort out if we can use the current value */
+ if (pInfo->idBuffer
+ && pInfo->cValues >= cValues
+ && !crMemcmp(pValue, &pInfo->Value, cbValue))
+ return GL_FALSE;
+
+ pBuffer = (GLfloat*)crAlloc(cbValues);
+ if (!pBuffer)
+ {
+ WARN(("crAlloc for pBuffer failed"));
+ return GL_FALSE;
+ }
+
+ pu8Buf = (uint8_t *)pBuffer;
+ for (i = 0; i < cValues; ++i)
+ {
+ crMemcpy(pu8Buf, pValue, cbValue);
+ pu8Buf += cbValue;
+ }
+
+ /* */
+ if (!pInfo->idBuffer)
+ {
+ pack_spu.self.GenBuffersARB(1, &pInfo->idBuffer);
+ Assert(pInfo->idBuffer);
+ }
+
+ pack_spu.self.BindBufferARB(GL_ARRAY_BUFFER_ARB, pInfo->idBuffer);
+
+ if (pInfo->cbBuffer < cbValues)
+ {
+ pack_spu.self.BufferDataARB(GL_ARRAY_BUFFER_ARB, cbValues, pBuffer, GL_DYNAMIC_DRAW_ARB);
+ pInfo->cbBuffer = cbValues;
+ }
+ else
+ {
+ pack_spu.self.BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, cbValues, pBuffer);
+ }
+
+ pInfo->cValues = cValues;
+ crMemcpy(&pInfo->Value, pValue, cbValue);
+
+ crFree(pBuffer);
+
+ return GL_TRUE;
+}
+
+typedef struct
+{
+ ContextInfo *pCtx;
+ GLuint idBuffer;
+ CRClientPointer cp;
+} CR_ZVA_RESTORE_CTX;
+
+static void packspuZvaEnable(ContextInfo *pCtx, const GLfloat *pValue, GLuint cValues, CR_ZVA_RESTORE_CTX *pRestoreCtx)
+{
+ CRContext *g = pCtx->clientState;
+
+ Assert(0);
+
+#ifdef DEBUG
+ {
+ CRContext *pCurState = crStateGetCurrent();
+
+ Assert(g == pCurState);
+ }
+#endif
+
+ pRestoreCtx->pCtx = pCtx;
+ pRestoreCtx->idBuffer = g->bufferobject.arrayBuffer ? g->bufferobject.arrayBuffer->id : 0;
+ pRestoreCtx->cp = g->client.array.a[0];
+
+ Assert(!pRestoreCtx->cp.enabled);
+
+ /* buffer ref count mechanism does not work actually atm,
+ * still ensure the buffer does not get destroyed if we fix it in the future */
+ if (pRestoreCtx->cp.buffer)
+ pRestoreCtx->cp.buffer->refCount++;
+
+ packspuZvaCreate(pCtx, pValue, cValues);
+
+ pack_spu.self.BindBufferARB(GL_ARRAY_BUFFER_ARB, pCtx->zvaBufferInfo.idBuffer);
+
+ pack_spu.self.VertexAttribPointerARB(0, 4, GL_FLOAT,
+ GL_FALSE, /*normalized*/
+ 0, /*stride*/
+ NULL /*addr*/);
+
+ pack_spu.self.EnableVertexAttribArrayARB(0);
+}
+
+static void packspuZvaDisable(CR_ZVA_RESTORE_CTX *pRestoreCtx)
+{
+ if (pRestoreCtx->cp.buffer)
+ pack_spu.self.BindBufferARB(GL_ARRAY_BUFFER_ARB, pRestoreCtx->cp.buffer->id);
+ else
+ pack_spu.self.BindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
+
+ pack_spu.self.VertexAttribPointerARB(0, pRestoreCtx->cp.size, pRestoreCtx->cp.type,
+ pRestoreCtx->cp.normalized, /*normalized*/
+ pRestoreCtx->cp.stride, /*stride*/
+ pRestoreCtx->cp.p);
+
+ if (pRestoreCtx->cp.enabled)
+ pack_spu.self.EnableVertexAttribArrayARB(0);
+ else
+ pack_spu.self.DisableVertexAttribArrayARB(0);
+
+ if (pRestoreCtx->cp.buffer)
+ {
+ if (pRestoreCtx->cp.buffer->id != pRestoreCtx->idBuffer)
+ pack_spu.self.BindBufferARB(GL_ARRAY_BUFFER_ARB, pRestoreCtx->idBuffer);
+
+ /* we have increased the refcount above, decrease it back */
+ pRestoreCtx->cp.buffer->refCount--;
+ }
+ else
+ {
+ if (pRestoreCtx->idBuffer)
+ pack_spu.self.BindBufferARB(GL_ARRAY_BUFFER_ARB, pRestoreCtx->idBuffer);
+ }
+
+#ifdef DEBUG
+ {
+ CRContext *g = pRestoreCtx->pCtx->clientState;
+ CRContext *pCurState = crStateGetCurrent();
+
+ Assert(g == pCurState);
+
+ Assert(pRestoreCtx->cp.p == g->client.array.a[0].p);
+ Assert(pRestoreCtx->cp.size == g->client.array.a[0].size);
+ Assert(pRestoreCtx->cp.type == g->client.array.a[0].type);
+ Assert(pRestoreCtx->cp.stride == g->client.array.a[0].stride);
+ Assert(pRestoreCtx->cp.enabled == g->client.array.a[0].enabled);
+ Assert(pRestoreCtx->cp.normalized == g->client.array.a[0].normalized);
+ Assert(pRestoreCtx->cp.bytesPerIndex == g->client.array.a[0].bytesPerIndex);
+# ifdef CR_ARB_vertex_buffer_object
+ Assert(pRestoreCtx->cp.buffer == g->client.array.a[0].buffer);
+# endif
+# ifdef CR_EXT_compiled_vertex_array
+ Assert(pRestoreCtx->cp.locked == g->client.array.a[0].locked);
+# endif
+ Assert(pRestoreCtx->idBuffer == (g->bufferobject.arrayBuffer ? g->bufferobject.arrayBuffer->id : 0));
+ }
+#endif
+}
+
+void PACKSPU_APIENTRY
+packspu_ArrayElement( GLint index )
+{
+/** @todo cash guest/host pointers calculation and use appropriate path here without crStateUseServerArrays call*/
+#if 1
+ GLboolean serverArrays = GL_FALSE;
+ GLuint cZvaValues = 0;
+ GLfloat aAttrib[4];
+
+#if CR_ARB_vertex_buffer_object
+ {
+ GET_CONTEXT(ctx);
+ /*crDebug("packspu_ArrayElement index:%i", index);*/
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object)
+ {
+ serverArrays = crStateUseServerArrays();
+ if (ctx->fCheckZerroVertAttr)
+ cZvaValues = crStateNeedDummyZeroVertexArray(thread->currentContext->clientState, &thread->packer->current, aAttrib);
+ }
+ }
+#endif
+
+ if (serverArrays
+#ifdef CR_FORCE_ZVA_EXPAND
+ && !cZvaValues
+#endif
+ ) {
+ CR_ZVA_RESTORE_CTX RestoreCtx;
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ Assert(cZvaValues < UINT32_MAX/2);
+
+ /* LockArraysEXT can not be executed between glBegin/glEnd pair, it also
+ * leads to vertexpointers being adjusted on the host side between glBegin/glEnd calls which
+ * produces unpredictable results. Locking is done before the glBegin call instead.
+ */
+ CRASSERT(!clientState->array.locked || clientState->array.synced);
+
+ if (cZvaValues)
+ packspuZvaEnable(ctx, aAttrib, cZvaValues, &RestoreCtx);
+
+ /* Send the DrawArrays command over the wire */
+ if (pack_spu.swap)
+ crPackArrayElementSWAP( index );
+ else
+ crPackArrayElement( index );
+
+ if (cZvaValues)
+ packspuZvaDisable(&RestoreCtx);
+ }
+ else {
+ /* evaluate locally */
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+#ifdef CR_FORCE_ZVA_SERVER_ARRAY
+ CR_ZVA_RESTORE_CTX RestoreCtx;
+
+ if (cZvaValues && cZvaValues < UINT32_MAX/2)
+ packspuZvaEnable(ctx, aAttrib, cZvaValues, &RestoreCtx);
+#endif
+
+ if (pack_spu.swap)
+ crPackExpandArrayElementSWAP( index, clientState, cZvaValues ? aAttrib : NULL );
+ else
+ crPackExpandArrayElement( index, clientState, cZvaValues ? aAttrib : NULL );
+
+#ifdef CR_FORCE_ZVA_SERVER_ARRAY
+ if (cZvaValues && cZvaValues < UINT32_MAX/2)
+ packspuZvaDisable(&RestoreCtx);
+#endif
+ }
+#else
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+ crPackExpandArrayElement(index, clientState, NULL);
+#endif
+}
+
+/*#define CR_USE_LOCKARRAYS*/
+#ifdef CR_USE_LOCKARRAYS
+# error "check Zero Vertex Attrib hack is supported properly!"
+#endif
+
+void PACKSPU_APIENTRY
+packspu_DrawElements( GLenum mode, GLsizei count, GLenum type, const GLvoid *indices )
+{
+ GLboolean serverArrays = GL_FALSE;
+ GLuint cZvaValues = 0;
+ GLfloat aAttrib[4];
+
+#if CR_ARB_vertex_buffer_object
+ GLboolean lockedArrays = GL_FALSE;
+ CRBufferObject *elementsBuffer;
+ {
+ GET_CONTEXT(ctx);
+ elementsBuffer = crStateGetCurrent()->bufferobject.elementsBuffer;
+ /*crDebug("DrawElements count=%d, indices=%p", count, indices);*/
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object)
+ {
+ serverArrays = crStateUseServerArrays();
+ if (ctx->fCheckZerroVertAttr)
+ cZvaValues = crStateNeedDummyZeroVertexArray(thread->currentContext->clientState, &thread->packer->current, aAttrib);
+ }
+ }
+
+# ifdef CR_USE_LOCKARRAYS
+ if (!serverArrays && !ctx->clientState->client.array.locked && (count>3)
+ && (!elementsBuffer || !elementsBuffer->id))
+ {
+ GLuint min, max;
+ GLsizei i;
+
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ {
+ GLubyte *pIdx = (GLubyte *)indices;
+ min = max = pIdx[0];
+ for (i=0; i<count; ++i)
+ {
+ if (pIdx[i]<min) min = pIdx[i];
+ else if (pIdx[i]>max) max = pIdx[i];
+ }
+ break;
+ }
+ case GL_UNSIGNED_SHORT:
+ {
+ GLushort *pIdx = (GLushort *)indices;
+ min = max = pIdx[0];
+ for (i=0; i<count; ++i)
+ {
+ if (pIdx[i]<min) min = pIdx[i];
+ else if (pIdx[i]>max) max = pIdx[i];
+ }
+ break;
+ }
+ case GL_UNSIGNED_INT:
+ {
+ GLuint *pIdx = (GLuint *)indices;
+ min = max = pIdx[0];
+ for (i=0; i<count; ++i)
+ {
+ if (pIdx[i]<min) min = pIdx[i];
+ else if (pIdx[i]>max) max = pIdx[i];
+ }
+ break;
+ }
+ default: crError("Unknown type 0x%x", type);
+ }
+
+ if ((max-min)<(GLuint)(2*count))
+ {
+ crStateLockArraysEXT(min, max-min+1);
+
+ serverArrays = crStateUseServerArrays();
+ if (serverArrays)
+ {
+ lockedArrays = GL_TRUE;
+ }
+ else
+ {
+ crStateUnlockArraysEXT();
+ }
+ }
+ }
+# endif
+#endif
+
+ if (serverArrays
+#ifdef CR_FORCE_ZVA_EXPAND
+ && !cZvaValues
+#endif
+ ) {
+ CR_ZVA_RESTORE_CTX RestoreCtx;
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ Assert(cZvaValues < UINT32_MAX/2);
+
+ if (cZvaValues)
+ packspuZvaEnable(ctx, aAttrib, cZvaValues, &RestoreCtx);
+
+ /*Note the comment in packspu_LockArraysEXT*/
+ if (clientState->array.locked && !clientState->array.synced)
+ {
+ crPackLockArraysEXT(clientState->array.lockFirst, clientState->array.lockCount);
+ clientState->array.synced = GL_TRUE;
+ }
+
+ /* Send the DrawArrays command over the wire */
+ if (pack_spu.swap)
+ crPackDrawElementsSWAP( mode, count, type, indices );
+ else
+ crPackDrawElements( mode, count, type, indices );
+
+ if (cZvaValues)
+ packspuZvaDisable(&RestoreCtx);
+ }
+ else {
+ /* evaluate locally */
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+#ifdef CR_FORCE_ZVA_SERVER_ARRAY
+ CR_ZVA_RESTORE_CTX RestoreCtx;
+
+ if (cZvaValues && cZvaValues < UINT32_MAX/2)
+ packspuZvaEnable(ctx, aAttrib, cZvaValues, &RestoreCtx);
+#endif
+
+ if (pack_spu.swap)
+ crPackExpandDrawElementsSWAP( mode, count, type, indices, clientState, cZvaValues ? aAttrib : NULL );
+ else
+ {
+ //packspu_Begin(mode);
+ crPackExpandDrawElements( mode, count, type, indices, clientState, cZvaValues ? aAttrib : NULL );
+ //packspu_End();
+ }
+
+#ifdef CR_FORCE_ZVA_SERVER_ARRAY
+ if (cZvaValues && cZvaValues < UINT32_MAX/2)
+ packspuZvaDisable(&RestoreCtx);
+#endif
+ }
+
+#if CR_ARB_vertex_buffer_object
+ if (lockedArrays)
+ {
+ packspu_UnlockArraysEXT();
+ }
+#endif
+}
+
+
+void PACKSPU_APIENTRY
+packspu_DrawRangeElements( GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices )
+{
+ GLboolean serverArrays = GL_FALSE;
+ GLuint cZvaValues = 0;
+ GLfloat aAttrib[4];
+
+#if CR_ARB_vertex_buffer_object
+ {
+ GET_CONTEXT(ctx);
+ /*crDebug("DrawRangeElements count=%d", count);*/
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object)
+ {
+ serverArrays = crStateUseServerArrays();
+ if (ctx->fCheckZerroVertAttr)
+ cZvaValues = crStateNeedDummyZeroVertexArray(thread->currentContext->clientState, &thread->packer->current, aAttrib);
+ }
+ }
+#endif
+
+ if (serverArrays
+#ifdef CR_FORCE_ZVA_EXPAND
+ && !cZvaValues
+#endif
+ ) {
+ CR_ZVA_RESTORE_CTX RestoreCtx;
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ Assert(cZvaValues < UINT32_MAX/2);
+
+ if (cZvaValues)
+ packspuZvaEnable(ctx, aAttrib, cZvaValues, &RestoreCtx);
+
+ /*Note the comment in packspu_LockArraysEXT*/
+ if (clientState->array.locked && !clientState->array.synced)
+ {
+ crPackLockArraysEXT(clientState->array.lockFirst, clientState->array.lockCount);
+ clientState->array.synced = GL_TRUE;
+ }
+
+ /* Send the DrawRangeElements command over the wire */
+ if (pack_spu.swap)
+ crPackDrawRangeElementsSWAP( mode, start, end, count, type, indices );
+ else
+ crPackDrawRangeElements( mode, start, end, count, type, indices );
+
+ if (cZvaValues)
+ packspuZvaDisable(&RestoreCtx);
+ }
+ else {
+ /* evaluate locally */
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+#ifdef CR_FORCE_ZVA_SERVER_ARRAY
+ CR_ZVA_RESTORE_CTX RestoreCtx;
+
+ if (cZvaValues && cZvaValues < UINT32_MAX/2)
+ packspuZvaEnable(ctx, aAttrib, cZvaValues, &RestoreCtx);
+#endif
+
+ if (pack_spu.swap)
+ crPackExpandDrawRangeElementsSWAP( mode, start, end, count, type, indices, clientState, cZvaValues ? aAttrib : NULL );
+ else
+ {
+ crPackExpandDrawRangeElements( mode, start, end, count, type, indices, clientState, cZvaValues ? aAttrib : NULL );
+ }
+
+#ifdef CR_FORCE_ZVA_SERVER_ARRAY
+ if (cZvaValues && cZvaValues < UINT32_MAX/2)
+ packspuZvaDisable(&RestoreCtx);
+#endif
+ }
+}
+
+
+void PACKSPU_APIENTRY
+packspu_DrawArrays( GLenum mode, GLint first, GLsizei count )
+{
+ GLboolean serverArrays = GL_FALSE;
+ GLuint cZvaValues = 0;
+ GLfloat aAttrib[4];
+
+#if CR_ARB_vertex_buffer_object
+ GLboolean lockedArrays = GL_FALSE;
+ {
+ GET_CONTEXT(ctx);
+ /*crDebug("DrawArrays count=%d", count);*/
+ if (ctx->clientState->extensions.ARB_vertex_buffer_object)
+ {
+ serverArrays = crStateUseServerArrays();
+ if (ctx->fCheckZerroVertAttr)
+ cZvaValues = crStateNeedDummyZeroVertexArray(thread->currentContext->clientState, &thread->packer->current, aAttrib);
+ }
+ }
+
+# ifdef CR_USE_LOCKARRAYS
+ if (!serverArrays && !ctx->clientState->client.array.locked && (count>3))
+ {
+ crStateLockArraysEXT(first, count);
+ serverArrays = crStateUseServerArrays();
+ if (serverArrays)
+ {
+ lockedArrays = GL_TRUE;
+ }
+ else
+ {
+ crStateUnlockArraysEXT();
+ }
+ }
+# endif
+#endif
+
+ if (serverArrays
+#ifdef CR_FORCE_ZVA_EXPAND
+ && !cZvaValues
+#endif
+ )
+ {
+ CR_ZVA_RESTORE_CTX RestoreCtx;
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ Assert(cZvaValues < UINT32_MAX/2);
+
+ if (cZvaValues)
+ packspuZvaEnable(ctx, aAttrib, cZvaValues, &RestoreCtx);
+
+ /*Note the comment in packspu_LockArraysEXT*/
+ if (clientState->array.locked && !clientState->array.synced)
+ {
+ crPackLockArraysEXT(clientState->array.lockFirst, clientState->array.lockCount);
+ clientState->array.synced = GL_TRUE;
+ }
+
+ /* Send the DrawArrays command over the wire */
+ if (pack_spu.swap)
+ crPackDrawArraysSWAP( mode, first, count );
+ else
+ crPackDrawArrays( mode, first, count );
+
+ if (cZvaValues)
+ packspuZvaDisable(&RestoreCtx);
+ }
+ else
+ {
+ /* evaluate locally */
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+#ifdef CR_FORCE_ZVA_SERVER_ARRAY
+ CR_ZVA_RESTORE_CTX RestoreCtx;
+
+ if (cZvaValues && cZvaValues < UINT32_MAX/2)
+ packspuZvaEnable(ctx, aAttrib, cZvaValues, &RestoreCtx);
+#endif
+
+ if (pack_spu.swap)
+ crPackExpandDrawArraysSWAP( mode, first, count, clientState, cZvaValues ? aAttrib : NULL );
+ else
+ crPackExpandDrawArrays( mode, first, count, clientState, cZvaValues ? aAttrib : NULL );
+
+#ifdef CR_FORCE_ZVA_SERVER_ARRAY
+ if (cZvaValues && cZvaValues < UINT32_MAX/2)
+ packspuZvaDisable(&RestoreCtx);
+#endif
+
+ }
+
+#if CR_ARB_vertex_buffer_object
+ if (lockedArrays)
+ {
+ packspu_UnlockArraysEXT();
+ }
+#endif
+}
+
+
+#ifdef CR_EXT_multi_draw_arrays
+void PACKSPU_APIENTRY packspu_MultiDrawArraysEXT( GLenum mode, GLint *first, GLsizei *count, GLsizei primcount )
+{
+ GLint i;
+ for (i = 0; i < primcount; i++) {
+ if (count[i] > 0) {
+ packspu_DrawArrays(mode, first[i], count[i]);
+ }
+ }
+}
+
+void PACKSPU_APIENTRY packspu_MultiDrawElementsEXT( GLenum mode, const GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount )
+{
+ GLint i;
+ for (i = 0; i < primcount; i++) {
+ if (count[i] > 0) {
+ packspu_DrawElements(mode, count[i], type, indices[i]);
+ }
+ }
+}
+#endif
+
+
+void PACKSPU_APIENTRY packspu_EnableClientState( GLenum array )
+{
+ crStateEnableClientState(array);
+ crPackEnableClientState(array);
+}
+
+void PACKSPU_APIENTRY packspu_DisableClientState( GLenum array )
+{
+ crStateDisableClientState(array);
+ crPackDisableClientState(array);
+}
+
+void PACKSPU_APIENTRY packspu_ClientActiveTextureARB( GLenum texUnit )
+{
+ crStateClientActiveTextureARB(texUnit);
+ crPackClientActiveTextureARB(texUnit);
+}
+
+void PACKSPU_APIENTRY packspu_EnableVertexAttribArrayARB(GLuint index)
+{
+ crStateEnableVertexAttribArrayARB(index);
+ crPackEnableVertexAttribArrayARB(index);
+}
+
+
+void PACKSPU_APIENTRY packspu_DisableVertexAttribArrayARB(GLuint index)
+{
+ crStateDisableVertexAttribArrayARB(index);
+ crPackDisableVertexAttribArrayARB(index);
+}
+
+void PACKSPU_APIENTRY packspu_Enable( GLenum cap )
+{
+ if (cap!=GL_LIGHT_MODEL_TWO_SIDE)
+ {
+ crStateEnable(cap);
+
+ if (pack_spu.swap)
+ crPackEnableSWAP(cap);
+ else
+ crPackEnable(cap);
+ }
+ else
+ {
+ static int g_glmts1_warn=0;
+ if (!g_glmts1_warn)
+ {
+ crWarning("glEnable(GL_LIGHT_MODEL_TWO_SIDE) converted to valid glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,1)");
+ g_glmts1_warn=1;
+ }
+ crStateLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
+ crPackLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
+ }
+}
+
+
+void PACKSPU_APIENTRY packspu_Disable( GLenum cap )
+{
+ if (cap!=GL_LIGHT_MODEL_TWO_SIDE)
+ {
+ crStateDisable(cap);
+
+ if (pack_spu.swap)
+ crPackDisableSWAP(cap);
+ else
+ crPackDisable(cap);
+ }
+ else
+ {
+ static int g_glmts0_warn=0;
+ if (!g_glmts0_warn)
+ {
+ crWarning("glDisable(GL_LIGHT_MODEL_TWO_SIDE) converted to valid glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,0)");
+ g_glmts0_warn=1;
+ }
+ crStateLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
+ crPackLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
+ }
+}
+
+GLboolean PACKSPU_APIENTRY packspu_IsEnabled(GLenum cap)
+{
+ GLboolean res = crStateIsEnabled(cap);
+#ifdef DEBUG
+ {
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLboolean return_val = (GLboolean) 0;
+ crPackIsEnabled(cap, &return_val, &writeback);
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ CRASSERT(return_val==res);
+ }
+#endif
+
+ return res;
+}
+
+void PACKSPU_APIENTRY packspu_PushClientAttrib( GLbitfield mask )
+{
+ crStatePushClientAttrib(mask);
+ crPackPushClientAttrib(mask);
+}
+
+void PACKSPU_APIENTRY packspu_PopClientAttrib( void )
+{
+ crStatePopClientAttrib();
+ crPackPopClientAttrib();
+}
+
+void PACKSPU_APIENTRY packspu_LockArraysEXT(GLint first, GLint count)
+{
+ if (first>=0 && count>0)
+ {
+ crStateLockArraysEXT(first, count);
+ /*Note: this is a workaround for quake3 based apps.
+ It's modifying vertex data between glLockArraysEXT and glDrawElements calls,
+ so we'd pass data to host right before the glDrawSomething or glBegin call.
+ */
+ /*crPackLockArraysEXT(first, count);*/
+ }
+ else crDebug("Ignoring packspu_LockArraysEXT: first:%i, count:%i", first, count);
+}
+
+void PACKSPU_APIENTRY packspu_UnlockArraysEXT()
+{
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ if (clientState->array.locked && clientState->array.synced)
+ {
+ crPackUnlockArraysEXT();
+ }
+
+ crStateUnlockArraysEXT();
+}
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_config.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_config.c
new file mode 100644
index 00000000..70d6f01c
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_config.c
@@ -0,0 +1,60 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "packspu.h"
+#include "cr_string.h"
+#include "cr_error.h"
+#include "cr_spu.h"
+#include "cr_mem.h"
+
+#include <stdio.h>
+
+static void __setDefaults( void )
+{
+ crMemZero(pack_spu.context, CR_MAX_CONTEXTS * sizeof(ContextInfo));
+ pack_spu.numContexts = 0;
+
+ crMemZero(pack_spu.thread, MAX_THREADS * sizeof(ThreadInfo));
+ pack_spu.numThreads = 0;
+}
+
+
+static void set_emit( void *foo, const char *response )
+{
+ RT_NOREF(foo);
+ sscanf( response, "%d", &(pack_spu.emit_GATHER_POST_SWAPBUFFERS) );
+}
+
+static void set_swapbuffer_sync( void *foo, const char *response )
+{
+ RT_NOREF(foo);
+ sscanf( response, "%d", &(pack_spu.swapbuffer_sync) );
+}
+
+
+
+/* No SPU options yet. Well.. not really..
+ */
+SPUOptions packSPUOptions[] = {
+ { "emit_GATHER_POST_SWAPBUFFERS", CR_BOOL, 1, "0", NULL, NULL,
+ "Emit a parameter after SwapBuffers", (SPUOptionCB)set_emit },
+
+ { "swapbuffer_sync", CR_BOOL, 1, "1", NULL, NULL,
+ "Sync on SwapBuffers", (SPUOptionCB) set_swapbuffer_sync },
+
+ { NULL, CR_BOOL, 0, NULL, NULL, NULL, NULL, NULL },
+};
+
+
+void packspuSetVBoxConfiguration( const SPU *child_spu )
+{
+ RT_NOREF(child_spu);
+ __setDefaults();
+ pack_spu.emit_GATHER_POST_SWAPBUFFERS = 0;
+ pack_spu.swapbuffer_sync = 0;
+ pack_spu.name = crStrdup("vboxhgcm://llp:7000");
+ pack_spu.buffer_size = 5 * 1024 * 1024;
+}
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_context.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_context.c
new file mode 100644
index 00000000..26e81dbd
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_context.c
@@ -0,0 +1,617 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "packspu.h"
+#include "cr_mem.h"
+#include "cr_packfunctions.h"
+#include "cr_string.h"
+#include "packspu_proto.h"
+
+/*
+ * Allocate a new ThreadInfo structure, setup a connection to the
+ * server, allocate/init a packer context, bind this ThreadInfo to
+ * the calling thread with crSetTSD().
+ * We'll always call this function at least once even if we're not
+ * using threads.
+ */
+ThreadInfo *packspuNewThread(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ struct VBOXUHGSMI *pHgsmi
+#else
+ void
+#endif
+)
+{
+ ThreadInfo *thread=NULL;
+ int i;
+
+#ifdef CHROMIUM_THREADSAFE
+ crLockMutex(&_PackMutex);
+#else
+ CRASSERT(pack_spu.numThreads == 0);
+#endif
+
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ CRASSERT(!CRPACKSPU_IS_WDDM_CRHGSMI() == !pHgsmi);
+#endif
+
+ CRASSERT(pack_spu.numThreads < MAX_THREADS);
+ for (i=0; i<MAX_THREADS; ++i)
+ {
+ if (!pack_spu.thread[i].inUse)
+ {
+ thread = &pack_spu.thread[i];
+ break;
+ }
+ }
+ CRASSERT(thread);
+
+ thread->inUse = GL_TRUE;
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI())
+ thread->id = crThreadID();
+ else
+ thread->id = THREAD_OFFSET_MAGIC + i;
+ thread->currentContext = NULL;
+ thread->bInjectThread = GL_FALSE;
+
+ /* connect to the server */
+ thread->netServer.name = crStrdup( pack_spu.name );
+ thread->netServer.buffer_size = pack_spu.buffer_size;
+ packspuConnectToServer( &(thread->netServer)
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , pHgsmi
+#endif
+ );
+ CRASSERT(thread->netServer.conn);
+ /* packer setup */
+ CRASSERT(thread->packer == NULL);
+ thread->packer = crPackNewContext( pack_spu.swap );
+ CRASSERT(thread->packer);
+ crPackInitBuffer( &(thread->buffer), crNetAlloc(thread->netServer.conn),
+ thread->netServer.conn->buffer_size, thread->netServer.conn->mtu );
+ thread->buffer.canBarf = thread->netServer.conn->Barf ? GL_TRUE : GL_FALSE;
+ crPackSetBuffer( thread->packer, &thread->buffer );
+ crPackFlushFunc( thread->packer, packspuFlush );
+ crPackFlushArg( thread->packer, (void *) thread );
+ crPackSendHugeFunc( thread->packer, packspuHuge );
+
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ crPackSetContext( thread->packer );
+ }
+
+
+#ifdef CHROMIUM_THREADSAFE
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ crSetTSD(&_PackTSD, thread);
+ }
+#endif
+
+ pack_spu.numThreads++;
+
+#ifdef CHROMIUM_THREADSAFE
+ crUnlockMutex(&_PackMutex);
+#endif
+ return thread;
+}
+
+GLint PACKSPU_APIENTRY
+packspu_VBoxConCreate(struct VBOXUHGSMI *pHgsmi)
+{
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ ThreadInfo * thread;
+ CRASSERT(CRPACKSPU_IS_WDDM_CRHGSMI());
+ CRASSERT(pHgsmi);
+
+ thread = packspuNewThread(pHgsmi);
+
+ if (thread)
+ {
+ CRASSERT(thread->id);
+ CRASSERT(thread->id - THREAD_OFFSET_MAGIC < RT_ELEMENTS(pack_spu.thread)
+ && GET_THREAD_VAL_ID(thread->id) == thread);
+ return thread->id;
+ }
+ crError("packspuNewThread failed");
+#else
+ RT_NOREF(pHgsmi);
+#endif
+ return 0;
+}
+
+void PACKSPU_APIENTRY
+packspu_VBoxConFlush(GLint con)
+{
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ GET_THREAD_ID(thread, con);
+ CRASSERT(con);
+ CRASSERT(CRPACKSPU_IS_WDDM_CRHGSMI());
+ CRASSERT(thread->packer);
+ packspuFlush((void *) thread);
+#else
+ RT_NOREF(con);
+ crError("VBoxConFlush not implemented!");
+#endif
+}
+
+void PACKSPU_APIENTRY
+packspu_VBoxConDestroy(GLint con)
+{
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ GET_THREAD_ID(thread, con);
+ CRASSERT(con);
+ CRASSERT(CRPACKSPU_IS_WDDM_CRHGSMI());
+ CRASSERT(pack_spu.numThreads>0);
+ CRASSERT(thread->packer);
+ packspuFlush((void *) thread);
+
+ crLockMutex(&_PackMutex);
+
+ crPackDeleteContext(thread->packer);
+
+ if (thread->buffer.pack)
+ {
+ crNetFree(thread->netServer.conn, thread->buffer.pack);
+ thread->buffer.pack = NULL;
+ }
+
+ crNetFreeConnection(thread->netServer.conn);
+
+ if (thread->netServer.name)
+ crFree(thread->netServer.name);
+
+ pack_spu.numThreads--;
+ /*note can't shift the array here, because other threads have TLS references to array elements*/
+ crMemZero(thread, sizeof(ThreadInfo));
+
+#if 0
+ if (&pack_spu.thread[pack_spu.idxThreadInUse]==thread)
+ {
+ int i;
+ crError("Should not be here since idxThreadInUse should be always 0 for the dummy connection created in packSPUInit!");
+ for (i=0; i<MAX_THREADS; ++i)
+ {
+ if (pack_spu.thread[i].inUse)
+ {
+ pack_spu.idxThreadInUse=i;
+ break;
+ }
+ }
+ }
+#endif
+ crUnlockMutex(&_PackMutex);
+#else
+ RT_NOREF(con);
+#endif
+}
+
+GLvoid PACKSPU_APIENTRY
+packspu_VBoxConChromiumParameteriCR(GLint con, GLenum param, GLint value)
+{
+ GET_THREAD(thread);
+ CRPackContext * curPacker = crPackGetContext();
+ ThreadInfo *curThread = thread;
+
+ CRASSERT(!curThread == !curPacker);
+ CRASSERT(!curThread || !curPacker || curThread->packer == curPacker);
+#ifdef CHROMIUM_THREADSAFE
+ crLockMutex(&_PackMutex);
+#endif
+
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ CRASSERT(!con == !CRPACKSPU_IS_WDDM_CRHGSMI());
+#endif
+
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ if (!con)
+ {
+ crError("connection should be specified!");
+ return;
+ }
+ thread = GET_THREAD_VAL_ID(con);
+ }
+ else
+ {
+ CRASSERT(!con);
+ if (!thread)
+ {
+ thread = packspuNewThread(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ NULL
+#endif
+ );
+ }
+ }
+ CRASSERT(thread);
+ CRASSERT(thread->packer);
+
+ crPackSetContext( thread->packer );
+
+ packspu_ChromiumParameteriCR(param, value);
+
+#ifdef CHROMIUM_THREADSAFE
+ crUnlockMutex(&_PackMutex);
+#endif
+
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ /* restore the packer context to the tls */
+ crPackSetContext(curPacker);
+ }
+}
+
+GLvoid PACKSPU_APIENTRY
+packspu_VBoxConChromiumParametervCR(GLint con, GLenum target, GLenum type, GLsizei count, const GLvoid *values)
+{
+ GET_THREAD(thread);
+ CRPackContext * curPacker = crPackGetContext();
+ ThreadInfo *curThread = thread;
+
+ CRASSERT(!curThread == !curPacker);
+ CRASSERT(!curThread || !curPacker || curThread->packer == curPacker);
+#ifdef CHROMIUM_THREADSAFE
+ crLockMutex(&_PackMutex);
+#endif
+
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ CRASSERT(!con == !CRPACKSPU_IS_WDDM_CRHGSMI());
+#endif
+
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ if (!con)
+ {
+ crError("connection should be specified!");
+ return;
+ }
+ thread = GET_THREAD_VAL_ID(con);
+ }
+ else
+ {
+ CRASSERT(!con);
+ if (!thread)
+ {
+ thread = packspuNewThread(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ NULL
+#endif
+ );
+ }
+ }
+ CRASSERT(thread);
+ CRASSERT(thread->packer);
+
+ crPackSetContext( thread->packer );
+
+ packspu_ChromiumParametervCR(target, type, count, values);
+
+#ifdef CHROMIUM_THREADSAFE
+ crUnlockMutex(&_PackMutex);
+#endif
+
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ /* restore the packer context to the tls */
+ crPackSetContext(curPacker);
+ }
+}
+
+GLint PACKSPU_APIENTRY
+packspu_VBoxCreateContext( GLint con, const char *dpyName, GLint visual, GLint shareCtx )
+{
+ GET_THREAD(thread);
+ CRPackContext * curPacker = crPackGetContext();
+ ThreadInfo *curThread = thread;
+ int writeback = 1;
+ GLint serverCtx = (GLint) -1;
+ int slot;
+
+ CRASSERT(!curThread == !curPacker);
+ CRASSERT(!curThread || !curPacker || curThread->packer == curPacker);
+#ifdef CHROMIUM_THREADSAFE
+ crLockMutex(&_PackMutex);
+#endif
+
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ CRASSERT(!con == !CRPACKSPU_IS_WDDM_CRHGSMI());
+#endif
+
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ if (!con)
+ {
+ crError("connection should be specified!");
+ return -1;
+ }
+ thread = GET_THREAD_VAL_ID(con);
+ }
+ else
+ {
+ CRASSERT(!con);
+ if (!thread)
+ {
+ thread = packspuNewThread(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ NULL
+#endif
+ );
+ }
+ }
+ CRASSERT(thread);
+ CRASSERT(thread->packer);
+
+ if (shareCtx > 0) {
+ /* translate to server ctx id */
+ shareCtx -= MAGIC_OFFSET;
+ if (shareCtx >= 0 && shareCtx < pack_spu.numContexts) {
+ shareCtx = pack_spu.context[shareCtx].serverCtx;
+ }
+ }
+
+ crPackSetContext( thread->packer );
+
+ /* Pack the command */
+ if (pack_spu.swap)
+ crPackCreateContextSWAP( dpyName, visual, shareCtx, &serverCtx, &writeback );
+ else
+ crPackCreateContext( dpyName, visual, shareCtx, &serverCtx, &writeback );
+
+ /* Flush buffer and get return value */
+ packspuFlush(thread);
+ if (!(thread->netServer.conn->actual_network))
+ {
+ /* HUMUNGOUS HACK TO MATCH SERVER NUMBERING
+ *
+ * The hack exists solely to make file networking work for now. This
+ * is totally gross, but since the server expects the numbers to start
+ * from 5000, we need to write them out this way. This would be
+ * marginally less gross if the numbers (500 and 5000) were maybe
+ * some sort of #define'd constants somewhere so the client and the
+ * server could be aware of how each other were numbering things in
+ * cases like file networking where they actually
+ * care.
+ *
+ * -Humper
+ *
+ */
+ serverCtx = 5000;
+ }
+ else {
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ if (pack_spu.swap) {
+ serverCtx = (GLint) SWAP32(serverCtx);
+ }
+ if (serverCtx < 0) {
+#ifdef CHROMIUM_THREADSAFE
+ crUnlockMutex(&_PackMutex);
+#endif
+ crWarning("Failure in packspu_CreateContext");
+
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ /* restore the packer context to the tls */
+ crPackSetContext(curPacker);
+ }
+ return -1; /* failed */
+ }
+ }
+
+ /* find an empty context slot */
+ for (slot = 0; slot < pack_spu.numContexts; slot++) {
+ if (!pack_spu.context[slot].clientState) {
+ /* found empty slot */
+ break;
+ }
+ }
+ if (slot == pack_spu.numContexts) {
+ pack_spu.numContexts++;
+ }
+
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ thread->currentContext = &pack_spu.context[slot];
+ pack_spu.context[slot].currentThread = thread;
+ }
+
+ /* Fill in the new context info */
+ /* XXX fix-up sharedCtx param here */
+ pack_spu.context[slot].clientState = crStateCreateContext(NULL, visual, NULL);
+ pack_spu.context[slot].clientState->bufferobject.retainBufferData = GL_TRUE;
+ pack_spu.context[slot].serverCtx = serverCtx;
+
+#ifdef CHROMIUM_THREADSAFE
+ crUnlockMutex(&_PackMutex);
+#endif
+
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ /* restore the packer context to the tls */
+ crPackSetContext(curPacker);
+ }
+
+ return MAGIC_OFFSET + slot;
+}
+
+GLint PACKSPU_APIENTRY
+packspu_CreateContext( const char *dpyName, GLint visual, GLint shareCtx )
+{
+ return packspu_VBoxCreateContext( 0, dpyName, visual, shareCtx );
+}
+
+
+void PACKSPU_APIENTRY packspu_DestroyContext( GLint ctx )
+{
+ GET_THREAD(thread);
+ ThreadInfo *curThread = thread;
+ const int slot = ctx - MAGIC_OFFSET;
+ ContextInfo *context, *curContext;
+ CRPackContext * curPacker = crPackGetContext();
+
+ CRASSERT(slot >= 0);
+ CRASSERT(slot < pack_spu.numContexts);
+
+ context = (slot >= 0 && slot < pack_spu.numContexts) ? &(pack_spu.context[slot]) : NULL;
+ curContext = curThread ? curThread->currentContext : NULL;
+
+ if (context)
+ {
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ thread = context->currentThread;
+ if (thread)
+ {
+ crPackSetContext(thread->packer);
+ CRASSERT(!(thread->packer == curPacker) == !(thread == curThread));
+ }
+ }
+
+ if (pack_spu.swap)
+ crPackDestroyContextSWAP( context->serverCtx );
+ else
+ crPackDestroyContext( context->serverCtx );
+
+ crStateDestroyContext( context->clientState );
+
+ context->clientState = NULL;
+ context->serverCtx = 0;
+ context->currentThread = NULL;
+
+ crMemset (&context->zvaBufferInfo, 0, sizeof (context->zvaBufferInfo));
+ }
+
+ if (curContext == context)
+ {
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ curThread->currentContext = NULL;
+ }
+ else
+ {
+ CRASSERT(thread == curThread);
+ crSetTSD(&_PackTSD, NULL);
+ crPackSetContext(NULL);
+ }
+ crStateMakeCurrent( NULL );
+ }
+ else
+ {
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ crPackSetContext(curPacker);
+ }
+ }
+}
+
+void PACKSPU_APIENTRY packspu_MakeCurrent( GLint window, GLint nativeWindow, GLint ctx )
+{
+ ThreadInfo *thread = NULL;
+ GLint serverCtx;
+ ContextInfo *newCtx = NULL;
+
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ thread = GET_THREAD_VAL();
+ if (!thread) {
+ thread = packspuNewThread(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ NULL
+#endif
+ );
+ }
+ CRASSERT(thread);
+ CRASSERT(thread->packer);
+ }
+
+ if (ctx) {
+ const int slot = ctx - MAGIC_OFFSET;
+
+ CRASSERT(slot >= 0);
+ CRASSERT(slot < pack_spu.numContexts);
+
+ newCtx = &pack_spu.context[slot];
+ CRASSERT(newCtx);
+ CRASSERT(newCtx->clientState); /* verify valid */
+
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ thread = newCtx->currentThread;
+ CRASSERT(thread);
+ crSetTSD(&_PackTSD, thread);
+ crPackSetContext( thread->packer );
+ }
+ else
+ {
+ CRASSERT(thread);
+ if (newCtx->fAutoFlush)
+ {
+ if (newCtx->currentThread && newCtx->currentThread != thread)
+ {
+ crLockMutex(&_PackMutex);
+ /* do a flush for the previously assigned thread
+ * to ensure all commands issued there are submitted */
+ if (newCtx->currentThread
+ && newCtx->currentThread->inUse
+ && newCtx->currentThread->netServer.conn
+ && newCtx->currentThread->packer && newCtx->currentThread->packer->currentBuffer)
+ {
+ packspuFlush((void *) newCtx->currentThread);
+ }
+ crUnlockMutex(&_PackMutex);
+ }
+ newCtx->currentThread = thread;
+ }
+
+ if (thread->currentContext && newCtx != thread->currentContext && thread->currentContext->fCheckZerroVertAttr)
+ crStateCurrentRecoverNew(thread->currentContext->clientState, &thread->packer->current);
+
+ thread->currentContext = newCtx;
+ crPackSetContext( thread->packer );
+ }
+
+ crStateMakeCurrent( newCtx->clientState );
+ //crStateSetCurrentPointers(newCtx->clientState, &thread->packer->current);
+ serverCtx = pack_spu.context[slot].serverCtx;
+ }
+ else {
+ crStateMakeCurrent( NULL );
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ thread = GET_THREAD_VAL();
+ if (!thread)
+ {
+ CRASSERT(crPackGetContext() == NULL);
+ return;
+ }
+ CRASSERT(thread->currentContext);
+ CRASSERT(thread->packer == crPackGetContext());
+ }
+ else
+ {
+ thread->currentContext = NULL;
+ }
+ newCtx = NULL;
+ serverCtx = 0;
+ }
+
+ if (pack_spu.swap)
+ crPackMakeCurrentSWAP( window, nativeWindow, serverCtx );
+ else
+ crPackMakeCurrent( window, nativeWindow, serverCtx );
+
+ if (serverCtx)
+ {
+ packspuInitStrings();
+ }
+
+ {
+ GET_THREAD(t);
+ (void) t;
+ CRASSERT(t);
+ }
+}
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_flush.py b/src/VBox/Additions/common/crOpenGL/pack/packspu_flush.py
new file mode 100755
index 00000000..5742bcb0
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_flush.py
@@ -0,0 +1,42 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+
+apiutil.CopyrightC()
+
+print("""
+/* DO NOT EDIT - this file generated by packspu_flush.py script */
+
+/* These are otherwise ordinary functions which require that the buffer be
+ * flushed immediately after packing the function.
+ */
+#include "cr_glstate.h"
+#include "cr_packfunctions.h"
+#include "packspu.h"
+#include "packspu_proto.h"
+""")
+
+keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+for func_name in apiutil.AllSpecials( "packspu_flush" ):
+ params = apiutil.Parameters(func_name)
+ print('void PACKSPU_APIENTRY packspu_%s(%s)' % ( func_name, apiutil.MakeDeclarationString(params)))
+ print('{')
+ print('\tGET_THREAD(thread);')
+ print('\tif (pack_spu.swap)')
+ print('\t{')
+ print('\t\tcrPack%sSWAP(%s);' % ( func_name, apiutil.MakeCallString( params ) ))
+ print('\t}')
+ print('\telse')
+ print('\t{')
+ print('\t\tcrPack%s(%s);' % ( func_name, apiutil.MakeCallString( params ) ))
+ print('\t}')
+ print('\tpackspuFlush( (void *) thread );')
+ print('}\n')
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_flush_special b/src/VBox/Additions/common/crOpenGL/pack/packspu_flush_special
new file mode 100644
index 00000000..a4896826
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_flush_special
@@ -0,0 +1,9 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+BarrierCreateCR
+BarrierExecCR
+SemaphoreCreateCR
+SemaphorePCR
+SemaphoreVCR
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_framebuffer.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_framebuffer.c
new file mode 100644
index 00000000..e94c0444
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_framebuffer.c
@@ -0,0 +1,143 @@
+/* $Id: packspu_framebuffer.c $ */
+
+/** @file
+ * VBox OpenGL FBO related functions
+ */
+
+/*
+ * Copyright (C) 2009-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include "packspu.h"
+#include "cr_packfunctions.h"
+#include "cr_net.h"
+#include "packspu_proto.h"
+
+void PACKSPU_APIENTRY
+packspu_FramebufferTexture1DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+ crStateFramebufferTexture1DEXT(target, attachment, textarget, texture, level);
+ crPackFramebufferTexture1DEXT(target, attachment, textarget, texture, level);
+}
+
+void PACKSPU_APIENTRY
+packspu_FramebufferTexture2DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+{
+ crStateFramebufferTexture2DEXT(target, attachment, textarget, texture, level);
+ crPackFramebufferTexture2DEXT(target, attachment, textarget, texture, level);
+}
+
+void PACKSPU_APIENTRY
+packspu_FramebufferTexture3DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
+{
+ crStateFramebufferTexture3DEXT(target, attachment, textarget, texture, level, zoffset);
+ crPackFramebufferTexture3DEXT(target, attachment, textarget, texture, level, zoffset);
+}
+
+void PACKSPU_APIENTRY
+packspu_BindFramebufferEXT(GLenum target, GLuint framebuffer)
+{
+ crStateBindFramebufferEXT(target, framebuffer);
+ crPackBindFramebufferEXT(target, framebuffer);
+}
+
+void PACKSPU_APIENTRY
+packspu_DeleteFramebuffersEXT(GLsizei n, const GLuint * framebuffers)
+{
+ crStateDeleteFramebuffersEXT(n, framebuffers);
+ crPackDeleteFramebuffersEXT(n, framebuffers);
+}
+
+void PACKSPU_APIENTRY
+packspu_DeleteRenderbuffersEXT(GLsizei n, const GLuint * renderbuffers)
+{
+ crStateDeleteRenderbuffersEXT(n, renderbuffers);
+ crPackDeleteRenderbuffersEXT(n, renderbuffers);
+}
+
+void PACKSPU_APIENTRY
+packspu_FramebufferRenderbufferEXT(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
+{
+ crStateFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, renderbuffer);
+ crPackFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, renderbuffer);
+}
+
+void PACKSPU_APIENTRY
+packspu_BindRenderbufferEXT(GLenum target, GLuint renderbuffer)
+{
+ crStateBindRenderbufferEXT(target, renderbuffer);
+ crPackBindRenderbufferEXT(target, renderbuffer);
+}
+
+GLenum PACKSPU_APIENTRY
+packspu_CheckFramebufferStatusEXT(GLenum target)
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLenum status = crStateCheckFramebufferStatusEXT(target);
+
+ if (status!=GL_FRAMEBUFFER_UNDEFINED)
+ {
+ return status;
+ }
+
+ crPackCheckFramebufferStatusEXT(target, &status, &writeback);
+
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ crStateSetFramebufferStatus(target, status);
+ return status;
+}
+
+void PACKSPU_APIENTRY packspu_GenFramebuffersEXT( GLsizei n, GLuint * framebuffers )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI() && !(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
+ {
+ crError( "packspu_GenFramebuffersEXT doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!" );
+ }
+ if (pack_spu.swap)
+ {
+ crPackGenFramebuffersEXTSWAP( n, framebuffers, &writeback );
+ }
+ else
+ {
+ crPackGenFramebuffersEXT( n, framebuffers, &writeback );
+ }
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ crStateRegFramebuffers(n, framebuffers);
+}
+
+void PACKSPU_APIENTRY packspu_GenRenderbuffersEXT( GLsizei n, GLuint * renderbuffers )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI() && !(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
+ {
+ crError( "packspu_GenRenderbuffersEXT doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!" );
+ }
+ if (pack_spu.swap)
+ {
+ crPackGenRenderbuffersEXTSWAP( n, renderbuffers, &writeback );
+ }
+ else
+ {
+ crPackGenRenderbuffersEXT( n, renderbuffers, &writeback );
+ }
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ crStateRegRenderbuffers(n, renderbuffers);
+}
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_get.py b/src/VBox/Additions/common/crOpenGL/pack/packspu_get.py
new file mode 100755
index 00000000..371abeaa
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_get.py
@@ -0,0 +1,250 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+
+apiutil.CopyrightC()
+
+print("""
+/* DO NOT EDIT - THIS FILE AUTOMATICALLY GENERATED BY packspu_get.py SCRIPT */
+#include "packspu.h"
+#include "cr_packfunctions.h"
+#include "cr_net.h"
+#include "cr_mem.h"
+#include "packspu_proto.h"
+""")
+
+print("""
+static GLboolean crPackIsPixelStoreParm(GLenum pname)
+{
+ if (pname == GL_UNPACK_ALIGNMENT
+ || pname == GL_UNPACK_ROW_LENGTH
+ || pname == GL_UNPACK_SKIP_PIXELS
+ || pname == GL_UNPACK_LSB_FIRST
+ || pname == GL_UNPACK_SWAP_BYTES
+#ifdef CR_OPENGL_VERSION_1_2
+ || pname == GL_UNPACK_IMAGE_HEIGHT
+#endif
+ || pname == GL_UNPACK_SKIP_ROWS
+ || pname == GL_PACK_ALIGNMENT
+ || pname == GL_PACK_ROW_LENGTH
+ || pname == GL_PACK_SKIP_PIXELS
+ || pname == GL_PACK_LSB_FIRST
+ || pname == GL_PACK_SWAP_BYTES
+#ifdef CR_OPENGL_VERSION_1_2
+ || pname == GL_PACK_IMAGE_HEIGHT
+#endif
+ || pname == GL_PACK_SKIP_ROWS)
+ {
+ return GL_TRUE;
+ }
+ return GL_FALSE;
+}
+""")
+
+from get_sizes import *
+
+easy_swaps = {
+ 'GenTextures': '(unsigned int) n',
+ 'GetClipPlane': '4',
+ 'GetPolygonStipple': '0'
+}
+
+simple_funcs = [ 'GetIntegerv', 'GetFloatv', 'GetDoublev', 'GetBooleanv' ]
+simple_swaps = [ 'SWAP32', 'SWAPFLOAT', 'SWAPDOUBLE', '(GLboolean) SWAP32' ]
+
+vertattr_get_funcs = [ 'GetVertexAttribdv' 'GetVertexAttribfv' 'GetVertexAttribiv' ]
+
+hard_funcs = {
+ 'GetLightfv': 'SWAPFLOAT',
+ 'GetLightiv': 'SWAP32',
+ 'GetMaterialfv': 'SWAPFLOAT',
+ 'GetMaterialiv': 'SWAP32',
+ 'GetTexEnvfv': 'SWAPFLOAT',
+ 'GetTexEnviv': 'SWAP32',
+ 'GetTexGendv': 'SWAPDOUBLE',
+ 'GetTexGenfv': 'SWAPFLOAT',
+ 'GetTexGeniv': 'SWAP32',
+ 'GetTexLevelParameterfv': 'SWAPFLOAT',
+ 'GetTexLevelParameteriv': 'SWAP32',
+ 'GetTexParameterfv': 'SWAPFLOAT',
+ 'GetTexParameteriv': 'SWAP32' }
+
+keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+for func_name in keys:
+ params = apiutil.Parameters(func_name)
+ return_type = apiutil.ReturnType(func_name)
+ if apiutil.FindSpecial( "packspu", func_name ):
+ continue
+
+ if "get" in apiutil.Properties(func_name):
+ print('%s PACKSPU_APIENTRY packspu_%s(%s)' % ( return_type, func_name, apiutil.MakeDeclarationString( params ) ))
+ print('{')
+ print('\tGET_THREAD(thread);')
+ print('\tint writeback = 1;')
+ if return_type != 'void':
+ print('\t%s return_val = (%s) 0;' % (return_type, return_type))
+ params.append( ("&return_val", "foo", 0) )
+ if (func_name in easy_swaps and easy_swaps[func_name] != '0') or func_name in simple_funcs or func_name in hard_funcs:
+ print('\tunsigned int i;')
+ print('\tif (!CRPACKSPU_IS_WDDM_CRHGSMI() && !(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))')
+ print('\t{')
+ print('\t\tcrError( "packspu_%s doesn\'t work when there\'s no actual network involved!\\nTry using the simplequery SPU in your chain!" );' % func_name)
+ print('\t}')
+ if func_name in simple_funcs:
+ print("""
+ if (crPackIsPixelStoreParm(pname)
+ || pname == GL_DRAW_BUFFER
+#ifdef CR_OPENGL_VERSION_1_3
+ || pname == GL_ACTIVE_TEXTURE
+#endif
+#ifdef CR_ARB_multitexture
+ || pname == GL_ACTIVE_TEXTURE_ARB
+#endif
+ || pname == GL_TEXTURE_BINDING_1D
+ || pname == GL_TEXTURE_BINDING_2D
+#ifdef CR_NV_texture_rectangle
+ || pname == GL_TEXTURE_BINDING_RECTANGLE_NV
+#endif
+#ifdef CR_ARB_texture_cube_map
+ || pname == GL_TEXTURE_BINDING_CUBE_MAP_ARB
+#endif
+#ifdef CR_ARB_vertex_program
+ || pname == GL_MAX_VERTEX_ATTRIBS_ARB
+#endif
+#ifdef GL_EXT_framebuffer_object
+ || pname == GL_FRAMEBUFFER_BINDING_EXT
+ || pname == GL_READ_FRAMEBUFFER_BINDING_EXT
+ || pname == GL_DRAW_FRAMEBUFFER_BINDING_EXT
+#endif
+ || pname == GL_ARRAY_BUFFER_BINDING
+ || pname == GL_ELEMENT_ARRAY_BUFFER_BINDING
+ || pname == GL_PIXEL_PACK_BUFFER_BINDING
+ || pname == GL_PIXEL_UNPACK_BUFFER_BINDING
+ )
+ {
+#ifdef DEBUG
+ if (!crPackIsPixelStoreParm(pname)
+#ifdef CR_ARB_vertex_program
+ && (pname!=GL_MAX_VERTEX_ATTRIBS_ARB)
+#endif
+ )
+ {
+ %s localparams;
+ localparams = (%s) crAlloc(__numValues(pname) * sizeof(*localparams));
+ crState%s(pname, localparams);
+ crPack%s(%s, &writeback);
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ for (i=0; i<__numValues(pname); ++i)
+ {
+ if (localparams[i] != params[i])
+ {
+ crWarning("Incorrect local state in %s for %%x param %%i", pname, i);
+ crWarning("Expected %%i but got %%i", (int)localparams[i], (int)params[i]);
+ }
+ }
+ crFree(localparams);
+ return;
+ }
+ else
+#endif
+ {
+ crState%s(pname, params);
+ return;
+ }
+
+ }
+ """ % (params[-1][1], params[-1][1], func_name, func_name, apiutil.MakeCallString(params), func_name, func_name))
+
+ if func_name in vertattr_get_funcs:
+ print("""
+ if (pname != GL_CURRENT_VERTEX_ATTRIB_ARB)
+ {
+#ifdef DEBUG
+ %s localparams;
+ localparams = (%s) crAlloc(__numValues(pname) * sizeof(*localparams));
+ crState%s(index, pname, localparams);
+ crPack%s(index, %s, &writeback);
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ for (i=0; i<crStateHlpComponentsCount(pname); ++i)
+ {
+ if (localparams[i] != params[i])
+ {
+ crWarning("Incorrect local state in %s for %%x param %%i", pname, i);
+ crWarning("Expected %%i but got %%i", (int)localparams[i], (int)params[i]);
+ }
+ }
+ crFree(localparams);
+#else
+ crState%s(pname, params);
+#endif
+ return;
+ }
+ """ % (params[-1][1], params[-1][1], func_name, func_name, apiutil.MakeCallString(params), func_name, func_name))
+
+ params.append( ("&writeback", "foo", 0) )
+ print('\tif (pack_spu.swap)')
+ print('\t{')
+ print('\t\tcrPack%sSWAP(%s);' % (func_name, apiutil.MakeCallString( params ) ))
+ print('\t}')
+ print('\telse')
+ print('\t{')
+ print('\t\tcrPack%s(%s);' % (func_name, apiutil.MakeCallString( params ) ))
+ print('\t}')
+ print('\tpackspuFlush( (void *) thread );')
+ print('\tCRPACKSPU_WRITEBACK_WAIT(thread, writeback);')
+
+
+
+ lastParamName = params[-2][0]
+ if return_type != 'void':
+ print('\tif (pack_spu.swap)')
+ print('\t{')
+ print('\t\treturn_val = (%s) SWAP32(return_val);' % return_type)
+ print('\t}')
+ print('\treturn return_val;')
+ if func_name in easy_swaps and easy_swaps[func_name] != '0':
+ limit = easy_swaps[func_name]
+ print('\tif (pack_spu.swap)')
+ print('\t{')
+ print('\t\tfor (i = 0; i < %s; i++)' % limit)
+ print('\t\t{')
+ if params[-2][1].find( "double" ) > -1:
+ print('\t\t\t%s[i] = SWAPDOUBLE(%s[i]);' % (lastParamName, lastParamName))
+ else:
+ print('\t\t\t%s[i] = SWAP32(%s[i]);' % (lastParamName, lastParamName))
+ print('\t\t}')
+ print('\t}')
+ for index in range(len(simple_funcs)):
+ if simple_funcs[index] == func_name:
+ print('\tif (pack_spu.swap)')
+ print('\t{')
+ print('\t\tfor (i = 0; i < __numValues(pname); i++)')
+ print('\t\t{')
+ if simple_swaps[index] == 'SWAPDOUBLE':
+ print('\t\t\t%s[i] = %s(%s[i]);' % (lastParamName, simple_swaps[index], lastParamName))
+ else:
+ print('\t\t\t((GLuint *) %s)[i] = %s(%s[i]);' % (lastParamName, simple_swaps[index], lastParamName))
+ print('\t\t}')
+ print('\t}')
+ if func_name in hard_funcs:
+ print('\tif (pack_spu.swap)')
+ print('\t{')
+ print('\t\tfor (i = 0; i < crStateHlpComponentsCount(pname); i++)')
+ print('\t\t{')
+ if hard_funcs[func_name] == 'SWAPDOUBLE':
+ print('\t\t\t%s[i] = %s(%s[i]);' % (lastParamName, hard_funcs[func_name], lastParamName))
+ else:
+ print('\t\t\t((GLuint *) %s)[i] = %s(%s[i]);' % (lastParamName, hard_funcs[func_name], lastParamName))
+ print('\t\t}')
+ print('\t}')
+ print('}\n')
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_getshaders.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_getshaders.c
new file mode 100644
index 00000000..97150222
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_getshaders.c
@@ -0,0 +1,214 @@
+/* $Id: packspu_getshaders.c $ */
+
+/** @file
+ * VBox OpenGL GLSL related functions
+ */
+
+/*
+ * Copyright (C) 2009-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include "packspu.h"
+#include "cr_packfunctions.h"
+#include "cr_net.h"
+#include "packspu_proto.h"
+#include "cr_mem.h"
+#include <iprt/assert.h>
+
+/** @todo combine with the one from server_getshaders.c*/
+typedef struct _crGetActive_t
+{
+ GLsizei length;
+ GLint size;
+ GLenum type;
+} crGetActive_t;
+
+void PACKSPU_APIENTRY packspu_GetActiveAttrib(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, char * name)
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ crGetActive_t *pLocal;
+
+ if (!size || !type || !name) return;
+
+ pLocal = (crGetActive_t*) crAlloc(bufSize+sizeof(crGetActive_t));
+ if (!pLocal) return;
+
+ crPackGetActiveAttrib(program, index, bufSize, (GLsizei*)pLocal, NULL, NULL, NULL, &writeback);
+
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ if (length) *length = pLocal->length;
+ *size = pLocal->size;
+ *type = pLocal->type;
+ crMemcpy(name, (char*)&pLocal[1], pLocal->length+1);
+ crFree(pLocal);
+}
+
+void PACKSPU_APIENTRY packspu_GetActiveUniform(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, char * name)
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ crGetActive_t *pLocal;
+
+ if (!size || !type || !name) return;
+
+ pLocal = (crGetActive_t*) crAlloc(bufSize+sizeof(crGetActive_t));
+ if (!pLocal) return;
+
+ crPackGetActiveUniform(program, index, bufSize, (GLsizei*)pLocal, NULL, NULL, NULL, &writeback);
+
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ if (length) *length = pLocal->length;
+ *size = pLocal->size;
+ *type = pLocal->type;
+ crMemcpy(name, &pLocal[1], pLocal->length+1);
+ crFree(pLocal);
+}
+
+void PACKSPU_APIENTRY packspu_GetAttachedShaders(GLuint program, GLsizei maxCount, GLsizei * count, GLuint * shaders)
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLsizei *pLocal;
+
+ if (!shaders) return;
+
+ pLocal = (GLsizei*) crAlloc(maxCount*sizeof(GLuint)+sizeof(GLsizei));
+ if (!pLocal) return;
+
+ crPackGetAttachedShaders(program, maxCount, pLocal, NULL, &writeback);
+
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ if (count) *count=*pLocal;
+ crMemcpy(shaders, &pLocal[1], *pLocal*sizeof(GLuint));
+ crFree(pLocal);
+}
+
+void PACKSPU_APIENTRY packspu_GetAttachedObjectsARB(VBoxGLhandleARB containerObj, GLsizei maxCount, GLsizei * count, VBoxGLhandleARB * obj)
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLsizei *pLocal;
+
+ if (!obj) return;
+
+ pLocal = (GLsizei*) crAlloc(maxCount*sizeof(VBoxGLhandleARB)+sizeof(GLsizei));
+ if (!pLocal) return;
+
+ crPackGetAttachedObjectsARB(containerObj, maxCount, pLocal, NULL, &writeback);
+
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ if (count) *count=*pLocal;
+ crMemcpy(obj, &pLocal[1], *pLocal*sizeof(VBoxGLhandleARB));
+ crFree(pLocal);
+}
+
+AssertCompile(sizeof(GLsizei) == 4);
+
+void PACKSPU_APIENTRY packspu_GetInfoLogARB(VBoxGLhandleARB obj, GLsizei maxLength, GLsizei * length, GLcharARB * infoLog)
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLsizei *pLocal;
+
+ if (!infoLog) return;
+
+ pLocal = (GLsizei*) crAlloc(maxLength+sizeof(GLsizei));
+ if (!pLocal) return;
+
+ crPackGetInfoLogARB(obj, maxLength, pLocal, NULL, &writeback);
+
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ CRASSERT((pLocal[0]) <= maxLength);
+
+ if (length) *length=*pLocal;
+ crMemcpy(infoLog, &pLocal[1], (maxLength >= (pLocal[0])) ? pLocal[0] : maxLength);
+ crFree(pLocal);
+}
+
+void PACKSPU_APIENTRY packspu_GetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei * length, char * infoLog)
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLsizei *pLocal;
+
+ if (!infoLog) return;
+
+ pLocal = (GLsizei*) crAlloc(bufSize+sizeof(GLsizei));
+ if (!pLocal) return;
+
+ crPackGetProgramInfoLog(program, bufSize, pLocal, NULL, &writeback);
+
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ if (length) *length=*pLocal;
+ crMemcpy(infoLog, &pLocal[1], (bufSize >= pLocal[0]) ? pLocal[0] : bufSize);
+ crFree(pLocal);
+}
+
+void PACKSPU_APIENTRY packspu_GetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei * length, char * infoLog)
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLsizei *pLocal;
+
+ if (!infoLog) return;
+
+ pLocal = (GLsizei*) crAlloc(bufSize+sizeof(GLsizei));
+ if (!pLocal) return;
+
+ crPackGetShaderInfoLog(shader, bufSize, pLocal, NULL, &writeback);
+
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ if (length) *length=*pLocal;
+ crMemcpy(infoLog, &pLocal[1], (bufSize >= pLocal[0]) ? pLocal[0] : bufSize);
+ crFree(pLocal);
+}
+
+void PACKSPU_APIENTRY packspu_GetShaderSource(GLuint shader, GLsizei bufSize, GLsizei * length, char * source)
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLsizei *pLocal;
+
+ if (!source) return;
+
+ pLocal = (GLsizei*) crAlloc(bufSize+sizeof(GLsizei));
+ if (!pLocal) return;
+
+ crPackGetShaderSource(shader, bufSize, pLocal, NULL, &writeback);
+
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ if (length) *length=*pLocal;
+ crMemcpy(source, &pLocal[1], (bufSize >= pLocal[0]) ? pLocal[0] : bufSize);
+
+ if (bufSize > pLocal[0])
+ {
+ source[pLocal[0]] = 0;
+ }
+
+ crFree(pLocal);
+}
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_getstring.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_getstring.c
new file mode 100644
index 00000000..c5890bfe
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_getstring.c
@@ -0,0 +1,211 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "packspu.h"
+#include "cr_packfunctions.h"
+#include "state/cr_statefuncs.h"
+#include "cr_string.h"
+#include "packspu_proto.h"
+#include "cr_mem.h"
+#include <locale.h>
+
+static GLubyte gpszExtensions[10000];
+#ifdef CR_OPENGL_VERSION_2_0
+static GLubyte gpszShadingVersion[255]="";
+#endif
+
+static void GetString(GLenum name, GLubyte *pszStr)
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+
+ if (pack_spu.swap)
+ crPackGetStringSWAP(name, pszStr, &writeback);
+ else
+ crPackGetString(name, pszStr, &writeback);
+ packspuFlush( (void *) thread );
+
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+}
+
+static GLfloat
+GetVersionString(void)
+{
+ static GLboolean fInitialized = GL_FALSE;
+ static GLfloat version = 0.;
+
+ if (!fInitialized)
+ {
+ GLubyte return_value[100];
+
+ GetString(GL_VERSION, return_value);
+ CRASSERT(crStrlen((char *)return_value) < 100);
+
+ version = crStrToFloat((char *) return_value);
+ version = crStateComputeVersion(version);
+
+ fInitialized = GL_TRUE;
+ }
+
+ return version;
+}
+
+static const GLubyte *
+GetExtensions(void)
+{
+ static GLboolean fInitialized = GL_FALSE;
+ if (!fInitialized)
+ {
+ GLubyte return_value[10*1000];
+ const GLubyte *extensions, *ext;
+ GET_THREAD(thread);
+ int writeback = 1;
+
+ if (pack_spu.swap)
+ {
+ crPackGetStringSWAP( GL_EXTENSIONS, return_value, &writeback );
+ }
+ else
+ {
+ crPackGetString( GL_EXTENSIONS, return_value, &writeback );
+ }
+ packspuFlush( (void *) thread );
+
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ CRASSERT(crStrlen((char *)return_value) < 10*1000);
+
+ /* OK, we got the result from the server. Now we have to
+ * intersect is with the set of extensions that Chromium understands
+ * and tack on the Chromium-specific extensions.
+ */
+ extensions = return_value;
+ ext = crStateMergeExtensions(1, &extensions);
+
+#ifdef Linux
+ /** @todo
+ *That's a hack to allow running Unity, it uses libnux which is calling extension functions
+ *without checking if it's being supported/exported.
+ *glActiveStencilFaceEXT seems to be actually supported but the extension string isn't exported (for ex. on ATI HD4870),
+ *which leads to libglew setting function pointer to NULL and crashing Unity.
+ */
+ sprintf((char*)gpszExtensions, "%s GL_EXT_stencil_two_side", ext);
+#else
+ sprintf((char*)gpszExtensions, "%s", ext);
+#endif
+ fInitialized = GL_TRUE;
+ }
+
+ return gpszExtensions;
+}
+
+#ifdef WINDOWS
+static bool packspuRunningUnderWine(void)
+{
+ return NULL != GetModuleHandle("wined3d.dll") || NULL != GetModuleHandle("wined3dwddm.dll") || NULL != GetModuleHandle("wined3dwddm-x86.dll");
+}
+#endif
+
+const GLubyte * PACKSPU_APIENTRY packspu_GetString( GLenum name )
+{
+ GET_CONTEXT(ctx);
+
+ switch(name)
+ {
+ case GL_EXTENSIONS:
+ return GetExtensions();
+ case GL_VERSION:
+#if 0 && defined(WINDOWS)
+ if (packspuRunningUnderWine())
+ {
+ GetString(GL_REAL_VERSION, ctx->pszRealVersion);
+ return ctx->pszRealVersion;
+ }
+ else
+#endif
+ {
+ char *oldlocale;
+ float version;
+
+ oldlocale = setlocale(LC_NUMERIC, NULL);
+ oldlocale = crStrdup(oldlocale);
+ setlocale(LC_NUMERIC, "C");
+
+ version = GetVersionString();
+ sprintf((char*)ctx->glVersion, "%.1f Chromium %s", version, CR_VERSION_STRING);
+
+ if (oldlocale)
+ {
+ setlocale(LC_NUMERIC, oldlocale);
+ crFree(oldlocale);
+ }
+
+ return ctx->glVersion;
+ }
+ case GL_VENDOR:
+#ifdef WINDOWS
+ if (packspuRunningUnderWine())
+ {
+ GetString(GL_REAL_VENDOR, ctx->pszRealVendor);
+ return ctx->pszRealVendor;
+ }
+ else
+#endif
+ {
+ return crStateGetString(name);
+ }
+ case GL_RENDERER:
+#ifdef WINDOWS
+ if (packspuRunningUnderWine())
+ {
+ GetString(GL_REAL_RENDERER, ctx->pszRealRenderer);
+ return ctx->pszRealRenderer;
+ }
+ else
+#endif
+ {
+ return crStateGetString(name);
+ }
+
+#ifdef CR_OPENGL_VERSION_2_0
+ case GL_SHADING_LANGUAGE_VERSION:
+ {
+ static GLboolean fInitialized = GL_FALSE;
+ if (!fInitialized)
+ {
+ GetString(GL_SHADING_LANGUAGE_VERSION, gpszShadingVersion);
+ fInitialized = GL_TRUE;
+ }
+ return gpszShadingVersion;
+ }
+#endif
+#ifdef GL_CR_real_vendor_strings
+ case GL_REAL_VENDOR:
+ GetString(GL_REAL_VENDOR, ctx->pszRealVendor);
+ return ctx->pszRealVendor;
+ case GL_REAL_VERSION:
+ GetString(GL_REAL_VERSION, ctx->pszRealVersion);
+ return ctx->pszRealVersion;
+ case GL_REAL_RENDERER:
+ GetString(GL_REAL_RENDERER, ctx->pszRealRenderer);
+ return ctx->pszRealRenderer;
+#endif
+ default:
+ return crStateGetString(name);
+ }
+}
+
+void packspuInitStrings()
+{
+ static GLboolean fInitialized = GL_FALSE;
+
+ if (!fInitialized)
+ {
+ packspu_GetString(GL_EXTENSIONS);
+ packspu_GetString(GL_VERSION);
+ fInitialized = GL_TRUE;
+ }
+}
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_glsl.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_glsl.c
new file mode 100644
index 00000000..1116b7d5
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_glsl.c
@@ -0,0 +1,275 @@
+/* $Id: packspu_glsl.c $ */
+
+/** @file
+ * VBox OpenGL GLSL related functions
+ */
+
+/*
+ * Copyright (C) 2009-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include "packspu.h"
+#include "cr_packfunctions.h"
+#include "cr_net.h"
+#include "packspu_proto.h"
+#include "cr_mem.h"
+
+
+GLuint PACKSPU_APIENTRY packspu_CreateProgram(void)
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLuint return_val = (GLuint) 0;
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI() && !(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
+ {
+ crError("packspu_CreateProgram doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!");
+ }
+ if (pack_spu.swap)
+ {
+ crPackCreateProgramSWAP(&return_val, &writeback);
+ }
+ else
+ {
+ crPackCreateProgram(&return_val, &writeback);
+ }
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ if (pack_spu.swap)
+ {
+ return_val = (GLuint) SWAP32(return_val);
+ }
+
+ crStateCreateProgram(return_val);
+
+ return return_val;
+}
+
+static GLint packspu_GetUniformLocationUncached(GLuint program, const char * name)
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLint return_val = (GLint) 0;
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI() && !(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
+ {
+ crError("packspu_GetUniformLocation doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!");
+ }
+ if (pack_spu.swap)
+ {
+ crPackGetUniformLocationSWAP(program, name, &return_val, &writeback);
+ }
+ else
+ {
+ crPackGetUniformLocation(program, name, &return_val, &writeback);
+ }
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ if (pack_spu.swap)
+ {
+ return_val = (GLint) SWAP32(return_val);
+ }
+ return return_val;
+}
+
+GLint PACKSPU_APIENTRY packspu_GetUniformLocation(GLuint program, const char * name)
+{
+ if (!crStateIsProgramUniformsCached(program))
+ {
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLsizei maxcbData;
+ GLsizei *pData;
+ GLint mu;
+
+ packspu_GetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &mu);
+ maxcbData = 16*mu*sizeof(char);
+
+ pData = (GLsizei *) crAlloc(maxcbData+sizeof(GLsizei));
+ if (!pData)
+ {
+ crWarning("packspu_GetUniformLocation: not enough memory, fallback to single query");
+ return packspu_GetUniformLocationUncached(program, name);
+ }
+
+ crPackGetUniformsLocations(program, maxcbData, pData, NULL, &writeback);
+
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ crStateGLSLProgramCacheUniforms(program, pData[0], &pData[1]);
+
+ CRASSERT(crStateIsProgramUniformsCached(program));
+
+ crFree(pData);
+ }
+
+ /*crDebug("packspu_GetUniformLocation(%d, %s)=%i", program, name, crStateGetUniformLocation(program, name));*/
+ return crStateGetUniformLocation(program, name);
+}
+
+static GLint PACKSPU_APIENTRY packspu_GetAttribLocationUnchached( GLuint program, const char * name )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLint return_val = (GLint) 0;
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI() && !(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
+ {
+ crError( "packspu_GetAttribLocation doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!" );
+ }
+ if (pack_spu.swap)
+ {
+ crPackGetAttribLocationSWAP( program, name, &return_val, &writeback );
+ }
+ else
+ {
+ crPackGetAttribLocation( program, name, &return_val, &writeback );
+ }
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ if (pack_spu.swap)
+ {
+ return_val = (GLint) SWAP32(return_val);
+ }
+ return return_val;
+}
+
+GLint PACKSPU_APIENTRY packspu_GetAttribLocation(GLuint program, const char * name)
+{
+ if (!(CR_VBOX_CAP_GETATTRIBSLOCATIONS & g_u32VBoxHostCaps))
+ return packspu_GetAttribLocationUnchached(program, name);
+
+ if (!crStateIsProgramAttribsCached(program))
+ {
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLsizei maxcbData;
+ GLsizei *pData;
+ GLint mu;
+
+ packspu_GetIntegerv(GL_MAX_VERTEX_ATTRIBS, &mu);
+ maxcbData = 4*32*mu*sizeof(char);
+
+ pData = (GLsizei *) crAlloc(maxcbData+sizeof(GLsizei));
+ if (!pData)
+ {
+ crWarning("packspu_GetAttribLocation: not enough memory, fallback to single query");
+ return packspu_GetAttribLocationUnchached(program, name);
+ }
+
+ crPackGetAttribsLocations(program, maxcbData, pData, NULL, &writeback);
+
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ crStateGLSLProgramCacheAttribs(program, pData[0], &pData[1]);
+
+ CRASSERT(crStateIsProgramAttribsCached(program));
+
+ crFree(pData);
+ }
+
+ /*crDebug("packspu_GetAttribLocation(%d, %s)=%i", program, name, crStateGetAttribLocation(program, name));*/
+ return crStateGetAttribLocation(program, name);
+}
+
+void PACKSPU_APIENTRY packspu_GetUniformsLocations(GLuint program, GLsizei maxcbData, GLsizei * cbData, GLvoid * pData)
+{
+ (void) program;
+ (void) maxcbData;
+ (void) cbData;
+ (void) pData;
+ WARN(("packspu_GetUniformsLocations shouldn't be called directly"));
+}
+
+void PACKSPU_APIENTRY packspu_GetAttribsLocations(GLuint program, GLsizei maxcbData, GLsizei * cbData, GLvoid * pData)
+{
+ (void) program;
+ (void) maxcbData;
+ (void) cbData;
+ (void) pData;
+ WARN(("packspu_GetAttribsLocations shouldn't be called directly"));
+}
+
+void PACKSPU_APIENTRY packspu_DeleteProgram(GLuint program)
+{
+ crStateDeleteProgram(program);
+ crPackDeleteProgram(program);
+}
+
+void PACK_APIENTRY packspu_DeleteObjectARB(VBoxGLhandleARB obj)
+{
+ GLuint hwid = crStateGetProgramHWID(obj);
+
+ CRASSERT(obj);
+
+ /* we do not track shader creation inside guest since it is not needed currently.
+ * this is why we only care about programs here */
+ if (hwid)
+ {
+ crStateDeleteProgram(obj);
+ }
+
+ crPackDeleteObjectARB(obj);
+}
+
+#ifdef VBOX_WITH_CRPACKSPU_DUMPER
+static void packspu_RecCheckInitRec()
+{
+ if (pack_spu.Recorder.pDumper)
+ return;
+
+ crDmpDbgPrintInit(&pack_spu.Dumper);
+
+ crRecInit(&pack_spu.Recorder, NULL /*pBlitter: we do not support blitter operations here*/, &pack_spu.self, &pack_spu.Dumper.Base);
+}
+#endif
+
+void PACKSPU_APIENTRY packspu_LinkProgram(GLuint program)
+{
+#ifdef VBOX_WITH_CRPACKSPU_DUMPER
+ GLint linkStatus = 0;
+#endif
+
+ crStateLinkProgram(program);
+ crPackLinkProgram(program);
+
+#ifdef VBOX_WITH_CRPACKSPU_DUMPER
+ pack_spu.self.GetObjectParameterivARB(program, GL_OBJECT_LINK_STATUS_ARB, &linkStatus);
+ Assert(linkStatus);
+ if (!linkStatus)
+ {
+ CRContext *ctx = crStateGetCurrent();
+ packspu_RecCheckInitRec();
+ crRecDumpProgram(&pack_spu.Recorder, ctx, program, program);
+ }
+#endif
+}
+
+void PACKSPU_APIENTRY packspu_CompileShader(GLuint shader)
+{
+#ifdef VBOX_WITH_CRPACKSPU_DUMPER
+ GLint compileStatus = 0;
+#endif
+
+// crStateCompileShader(shader);
+ crPackCompileShader(shader);
+
+#ifdef VBOX_WITH_CRPACKSPU_DUMPER
+ pack_spu.self.GetObjectParameterivARB(shader, GL_OBJECT_COMPILE_STATUS_ARB, &compileStatus);
+ Assert(compileStatus);
+ if (!compileStatus)
+ {
+ CRContext *ctx = crStateGetCurrent();
+ packspu_RecCheckInitRec();
+ crRecDumpShader(&pack_spu.Recorder, ctx, shader, shader);
+ }
+#endif
+}
+
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_init.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_init.c
new file mode 100644
index 00000000..d5219950
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_init.c
@@ -0,0 +1,152 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "cr_mem.h"
+#include "cr_spu.h"
+#include "cr_glstate.h"
+#include "packspu.h"
+#include "cr_packfunctions.h"
+#include <stdio.h>
+
+extern SPUNamedFunctionTable _cr_pack_table[];
+
+SPUFunctions pack_functions = {
+ NULL, /* CHILD COPY */
+ NULL, /* DATA */
+ _cr_pack_table /* THE ACTUAL FUNCTIONS */
+};
+
+PackSPU pack_spu;
+
+#ifdef CHROMIUM_THREADSAFE
+CRtsd _PackTSD;
+CRmutex _PackMutex;
+#endif
+
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+# include <VBoxCrHgsmi.h>
+# include <VBoxUhgsmi.h>
+#endif
+
+#if defined(RT_OS_WINDOWS) && defined(VBOX_WITH_WDDM)
+static bool isVBoxWDDMCrHgsmi(void)
+{
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ PVBOXUHGSMI pHgsmi = VBoxCrHgsmiCreate();
+ if (pHgsmi)
+ {
+ VBoxCrHgsmiDestroy(pHgsmi);
+ return true;
+ }
+#endif
+ return false;
+}
+#endif /* RT_OS_WINDOWS && VBOX_WITH_WDDM */
+
+static SPUFunctions *
+packSPUInit( int id, SPU *child, SPU *self,
+ unsigned int context_id,
+ unsigned int num_contexts )
+{
+ ThreadInfo *thread;
+
+ (void) context_id;
+ (void) num_contexts;
+ (void) child;
+ (void) self;
+
+#if defined(CHROMIUM_THREADSAFE) && !defined(WINDOWS)
+ crInitMutex(&_PackMutex);
+#endif
+
+#ifdef CHROMIUM_THREADSAFE
+ crInitTSD(&_PackerTSD);
+ crInitTSD(&_PackTSD);
+#endif
+
+ pack_spu.id = id;
+
+ packspuSetVBoxConfiguration( child );
+
+#if defined(WINDOWS) && defined(VBOX_WITH_WDDM)
+ pack_spu.bIsWDDMCrHgsmi = isVBoxWDDMCrHgsmi();
+#endif
+
+#ifdef VBOX_WITH_CRPACKSPU_DUMPER
+ memset(&pack_spu.Dumper, 0, sizeof (pack_spu.Dumper));
+#endif
+
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ /* This connects to the server, sets up the packer, etc. */
+ thread = packspuNewThread(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ NULL
+#endif
+ );
+
+ if (!thread) {
+ return NULL;
+ }
+ CRASSERT( thread == &(pack_spu.thread[0]) );
+ pack_spu.idxThreadInUse = 0;
+ }
+
+ packspuCreateFunctions();
+ crStateInit();
+
+ return &pack_functions;
+}
+
+static void
+packSPUSelfDispatch(SPUDispatchTable *self)
+{
+ crSPUInitDispatchTable( &(pack_spu.self) );
+ crSPUCopyDispatchTable( &(pack_spu.self), self );
+}
+
+static int
+packSPUCleanup(void)
+{
+ int i;
+#ifdef CHROMIUM_THREADSAFE
+ crLockMutex(&_PackMutex);
+#endif
+ for (i=0; i<MAX_THREADS; ++i)
+ {
+ if (pack_spu.thread[i].inUse && pack_spu.thread[i].packer)
+ {
+ crPackDeleteContext(pack_spu.thread[i].packer);
+ }
+ }
+
+#ifdef CHROMIUM_THREADSAFE
+ crFreeTSD(&_PackerTSD);
+ crFreeTSD(&_PackTSD);
+ crUnlockMutex(&_PackMutex);
+# ifndef WINDOWS
+ crFreeMutex(&_PackMutex);
+# endif
+#endif /* CHROMIUM_THREADSAFE */
+ return 1;
+}
+
+extern SPUOptions packSPUOptions[];
+
+int SPULoad( char **name, char **super, SPUInitFuncPtr *init,
+ SPUSelfDispatchFuncPtr *self, SPUCleanupFuncPtr *cleanup,
+ SPUOptionsPtr *options, int *flags )
+{
+ *name = "pack";
+ *super = NULL;
+ *init = packSPUInit;
+ *self = packSPUSelfDispatch;
+ *cleanup = packSPUCleanup;
+ *options = packSPUOptions;
+ *flags = (SPU_HAS_PACKER|SPU_IS_TERMINAL|SPU_MAX_SERVERS_ONE);
+
+ return 1;
+}
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_misc.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_misc.c
new file mode 100644
index 00000000..0b65be90
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_misc.c
@@ -0,0 +1,856 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "cr_packfunctions.h"
+#include "packspu.h"
+#include "packspu_proto.h"
+#include "cr_mem.h"
+
+void PACKSPU_APIENTRY packspu_ChromiumParametervCR(GLenum target, GLenum type, GLsizei count, const GLvoid *values)
+{
+
+ CRMessage msg;
+ int len;
+ GLint ai32ServerValues[2];
+ GLboolean fFlush = GL_FALSE;
+ GET_THREAD(thread);
+
+
+ switch(target)
+ {
+ case GL_GATHER_PACK_CR:
+ /* flush the current pack buffer */
+ packspuFlush( (void *) thread );
+
+ /* the connection is thread->server.conn */
+ msg.header.type = CR_MESSAGE_GATHER;
+ msg.gather.offset = 69;
+ len = sizeof(CRMessageGather);
+ crNetSend(thread->netServer.conn, NULL, &msg, len);
+ return;
+
+ case GL_SHARE_LISTS_CR:
+ {
+ ContextInfo *pCtx[2];
+ GLint *ai32Values;
+ int i;
+ if (count != 2)
+ {
+ WARN(("GL_SHARE_LISTS_CR invalid cound %d", count));
+ return;
+ }
+
+ if (type != GL_UNSIGNED_INT && type != GL_INT)
+ {
+ WARN(("GL_SHARE_LISTS_CR invalid type %d", type));
+ return;
+ }
+
+ ai32Values = (GLint*)values;
+
+ for (i = 0; i < 2; ++i)
+ {
+ const int slot = ai32Values[i] - MAGIC_OFFSET;
+
+ if (slot < 0 || slot >= pack_spu.numContexts)
+ {
+ WARN(("GL_SHARE_LISTS_CR invalid value[%d] %d", i, ai32Values[i]));
+ return;
+ }
+
+ pCtx[i] = &pack_spu.context[slot];
+ if (!pCtx[i]->clientState)
+ {
+ WARN(("GL_SHARE_LISTS_CR invalid pCtx1 for value[%d] %d", i, ai32Values[i]));
+ return;
+ }
+
+ ai32ServerValues[i] = pCtx[i]->serverCtx;
+ }
+
+ crStateShareLists(pCtx[0]->clientState, pCtx[1]->clientState);
+
+ values = ai32ServerValues;
+
+ fFlush = GL_TRUE;
+
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ if (pack_spu.swap)
+ crPackChromiumParametervCRSWAP(target, type, count, values);
+ else
+ crPackChromiumParametervCR(target, type, count, values);
+
+ if (fFlush)
+ packspuFlush( (void *) thread );
+}
+
+GLboolean packspuSyncOnFlushes(void)
+{
+#if 1 /*Seems to still cause issues, always sync for now*/
+ return 1;
+#else
+ GLint buffer;
+
+ crStateGetIntegerv(GL_DRAW_BUFFER, &buffer);
+ /*Usually buffer==GL_BACK, so put this extra check to simplify boolean eval on runtime*/
+ return (buffer != GL_BACK)
+ && (buffer == GL_FRONT_LEFT
+ || buffer == GL_FRONT_RIGHT
+ || buffer == GL_FRONT
+ || buffer == GL_FRONT_AND_BACK
+ || buffer == GL_LEFT
+ || buffer == GL_RIGHT);
+#endif
+}
+
+void PACKSPU_APIENTRY packspu_DrawBuffer(GLenum mode)
+{
+ GLboolean hadtoflush;
+
+ hadtoflush = packspuSyncOnFlushes();
+
+ crStateDrawBuffer(mode);
+ crPackDrawBuffer(mode);
+
+ if (hadtoflush && !packspuSyncOnFlushes())
+ packspu_Flush();
+}
+
+void PACKSPU_APIENTRY packspu_Finish( void )
+{
+ GET_THREAD(thread);
+ GLint writeback = CRPACKSPU_IS_WDDM_CRHGSMI() ? 1 : pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network;
+
+ if (pack_spu.swap)
+ {
+ crPackFinishSWAP();
+ }
+ else
+ {
+ crPackFinish();
+ }
+
+ if (packspuSyncOnFlushes())
+ {
+ if (writeback)
+ {
+ if (pack_spu.swap)
+ crPackWritebackSWAP(&writeback);
+ else
+ crPackWriteback(&writeback);
+
+ packspuFlush( (void *) thread );
+
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ }
+ }
+}
+
+void PACKSPU_APIENTRY packspu_Flush( void )
+{
+ GET_THREAD(thread);
+ int writeback=1;
+ int found=0;
+
+ if (!thread->bInjectThread)
+ {
+ crPackFlush();
+ if (packspuSyncOnFlushes())
+ {
+ crPackWriteback(&writeback);
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ }
+ }
+ else
+ {
+ int i;
+
+ crLockMutex(&_PackMutex);
+
+ /*Make sure we process commands in order they should appear, so flush other threads first*/
+ for (i=0; i<MAX_THREADS; ++i)
+ {
+ if (pack_spu.thread[i].inUse
+ && (thread != &pack_spu.thread[i]) && pack_spu.thread[i].netServer.conn
+ && pack_spu.thread[i].packer && pack_spu.thread[i].packer->currentBuffer)
+ {
+ packspuFlush((void *) &pack_spu.thread[i]);
+
+ if (pack_spu.thread[i].netServer.conn->u32ClientID == thread->netServer.conn->u32InjectClientID)
+ {
+ found=1;
+ }
+
+ }
+ }
+
+ if (!found)
+ {
+ /*Thread we're supposed to inject commands for has been detached,
+ so there's nothing to sync with and we should just pass commands through our own connection.
+ */
+ thread->netServer.conn->u32InjectClientID=0;
+ }
+
+ packspuFlush((void *) thread);
+
+ crUnlockMutex(&_PackMutex);
+ }
+}
+
+void PACKSPU_APIENTRY packspu_NewList(GLuint list, GLenum mode)
+{
+ crStateNewList(list, mode);
+ crPackNewList(list, mode);
+}
+
+void PACKSPU_APIENTRY packspu_EndList()
+{
+ crStateEndList();
+ crPackEndList();
+}
+
+void PACKSPU_APIENTRY packspu_VBoxWindowDestroy( GLint con, GLint window )
+{
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ GET_THREAD(thread);
+ if (con)
+ {
+ CRPackContext * curPacker = crPackGetContext();
+ CRASSERT(!thread || !thread->bInjectThread);
+ thread = GET_THREAD_VAL_ID(con);
+ crPackSetContext(thread->packer);
+ crPackWindowDestroy(window);
+ if (curPacker != thread->packer)
+ crPackSetContext(curPacker);
+ return;
+ }
+ CRASSERT(thread);
+ CRASSERT(thread->bInjectThread);
+ }
+ crPackWindowDestroy(window);
+}
+
+GLint PACKSPU_APIENTRY packspu_VBoxWindowCreate( GLint con, const char *dpyName, GLint visBits )
+{
+ GET_THREAD(thread);
+ static int num_calls = 0;
+ int writeback = CRPACKSPU_IS_WDDM_CRHGSMI() ? 1 : pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network;
+ GLint return_val = (GLint) 0;
+ ThreadInfo *curThread = thread;
+ GLint retVal;
+
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ if (!con)
+ {
+ crError("connection expected!");
+ return 0;
+ }
+ thread = GET_THREAD_VAL_ID(con);
+ }
+ else
+ {
+ CRASSERT(!con);
+ if (!thread) {
+ thread = packspuNewThread(
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ NULL
+#endif
+ );
+ }
+ }
+ CRASSERT(thread);
+ CRASSERT(thread->packer);
+ CRASSERT(crPackGetContext() == (curThread ? curThread->packer : NULL));
+
+ crPackSetContext(thread->packer);
+
+ if (pack_spu.swap)
+ {
+ crPackWindowCreateSWAP( dpyName, visBits, &return_val, &writeback );
+ }
+ else
+ {
+ crPackWindowCreate( dpyName, visBits, &return_val, &writeback );
+ }
+ packspuFlush(thread);
+ if (!(thread->netServer.conn->actual_network))
+ {
+ retVal = num_calls++;
+ }
+ else
+ {
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ if (pack_spu.swap)
+ {
+ return_val = (GLint) SWAP32(return_val);
+ }
+ retVal = return_val;
+ }
+
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ if (thread != curThread)
+ {
+ if (curThread)
+ crPackSetContext(curThread->packer);
+ else
+ crPackSetContext(NULL);
+ }
+ }
+
+ return retVal;
+}
+
+GLint PACKSPU_APIENTRY packspu_WindowCreate( const char *dpyName, GLint visBits )
+{
+ return packspu_VBoxWindowCreate( 0, dpyName, visBits );
+}
+
+GLboolean PACKSPU_APIENTRY
+packspu_AreTexturesResident( GLsizei n, const GLuint * textures,
+ GLboolean * residences )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLboolean return_val = GL_TRUE;
+ GLsizei i;
+
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI() && !(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
+ {
+ crError( "packspu_AreTexturesResident doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!" );
+ }
+
+ if (pack_spu.swap)
+ {
+ crPackAreTexturesResidentSWAP( n, textures, residences, &return_val, &writeback );
+ }
+ else
+ {
+ crPackAreTexturesResident( n, textures, residences, &return_val, &writeback );
+ }
+ packspuFlush( (void *) thread );
+
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ /* Since the Chromium packer/unpacker can't return both 'residences'
+ * and the function's return value, compute the return value here.
+ */
+ for (i = 0; i < n; i++) {
+ if (!residences[i]) {
+ return_val = GL_FALSE;
+ break;
+ }
+ }
+
+ return return_val;
+}
+
+
+GLboolean PACKSPU_APIENTRY
+packspu_AreProgramsResidentNV( GLsizei n, const GLuint * ids,
+ GLboolean * residences )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLboolean return_val = GL_TRUE;
+ GLsizei i;
+
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI() && !(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
+ {
+ crError( "packspu_AreProgramsResidentNV doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!" );
+ }
+ if (pack_spu.swap)
+ {
+ crPackAreProgramsResidentNVSWAP( n, ids, residences, &return_val, &writeback );
+ }
+ else
+ {
+ crPackAreProgramsResidentNV( n, ids, residences, &return_val, &writeback );
+ }
+ packspuFlush( (void *) thread );
+
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ /* Since the Chromium packer/unpacker can't return both 'residences'
+ * and the function's return value, compute the return value here.
+ */
+ for (i = 0; i < n; i++) {
+ if (!residences[i]) {
+ return_val = GL_FALSE;
+ break;
+ }
+ }
+
+ return return_val;
+}
+
+void PACKSPU_APIENTRY packspu_GetPolygonStipple( GLubyte * mask )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+
+ if (pack_spu.swap)
+ {
+ crPackGetPolygonStippleSWAP( mask, &writeback );
+ }
+ else
+ {
+ crPackGetPolygonStipple( mask, &writeback );
+ }
+
+#ifdef CR_ARB_pixel_buffer_object
+ if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+#endif
+ {
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ }
+}
+
+void PACKSPU_APIENTRY packspu_GetPixelMapfv( GLenum map, GLfloat * values )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+
+ if (pack_spu.swap)
+ {
+ crPackGetPixelMapfvSWAP( map, values, &writeback );
+ }
+ else
+ {
+ crPackGetPixelMapfv( map, values, &writeback );
+ }
+
+#ifdef CR_ARB_pixel_buffer_object
+ if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+#endif
+ {
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ }
+}
+
+void PACKSPU_APIENTRY packspu_GetPixelMapuiv( GLenum map, GLuint * values )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+
+ if (pack_spu.swap)
+ {
+ crPackGetPixelMapuivSWAP( map, values, &writeback );
+ }
+ else
+ {
+ crPackGetPixelMapuiv( map, values, &writeback );
+ }
+
+#ifdef CR_ARB_pixel_buffer_object
+ if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+#endif
+ {
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ }
+}
+
+void PACKSPU_APIENTRY packspu_GetPixelMapusv( GLenum map, GLushort * values )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+
+ if (pack_spu.swap)
+ {
+ crPackGetPixelMapusvSWAP( map, values, &writeback );
+ }
+ else
+ {
+ crPackGetPixelMapusv( map, values, &writeback );
+ }
+
+#ifdef CR_ARB_pixel_buffer_object
+ if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+#endif
+ {
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ }
+}
+
+static void packspuFluchOnThreadSwitch(GLboolean fEnable)
+{
+ GET_THREAD(thread);
+ if (thread->currentContext->fAutoFlush == fEnable)
+ return;
+
+ thread->currentContext->fAutoFlush = fEnable;
+ thread->currentContext->currentThread = fEnable ? thread : NULL;
+}
+
+static void packspuCheckZerroVertAttr(GLboolean fEnable)
+{
+ GET_THREAD(thread);
+
+ thread->currentContext->fCheckZerroVertAttr = fEnable;
+}
+
+void PACKSPU_APIENTRY packspu_ChromiumParameteriCR(GLenum target, GLint value)
+{
+ switch (target)
+ {
+ case GL_FLUSH_ON_THREAD_SWITCH_CR:
+ /* this is a pure packspu state, don't propagate it any further */
+ packspuFluchOnThreadSwitch(value);
+ return;
+ case GL_CHECK_ZERO_VERT_ARRT:
+ packspuCheckZerroVertAttr(value);
+ return;
+ case GL_SHARE_CONTEXT_RESOURCES_CR:
+ crStateShareContext(value);
+ break;
+ case GL_RCUSAGE_TEXTURE_SET_CR:
+ {
+ Assert(value);
+ crStateSetTextureUsed(value, GL_TRUE);
+ break;
+ }
+ case GL_RCUSAGE_TEXTURE_CLEAR_CR:
+ {
+ Assert(value);
+#ifdef DEBUG
+ {
+ CRContext *pCurState = crStateGetCurrent();
+ CRTextureObj *tobj = (CRTextureObj*)crHashtableSearch(pCurState->shared->textureTable, value);
+ Assert(tobj);
+ }
+#endif
+ crStateSetTextureUsed(value, GL_FALSE);
+ break;
+ }
+ default:
+ break;
+ }
+ crPackChromiumParameteriCR(target, value);
+}
+
+GLenum PACKSPU_APIENTRY packspu_GetError( void )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ GLenum return_val = (GLenum) 0;
+ CRContext *pCurState = crStateGetCurrent();
+ NOREF(pCurState); /* it's unused, but I don't know about side effects.. */
+
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI() && !(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
+ {
+ crError( "packspu_GetError doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!" );
+ }
+ if (pack_spu.swap)
+ {
+ crPackGetErrorSWAP( &return_val, &writeback );
+ }
+ else
+ {
+ crPackGetError( &return_val, &writeback );
+ }
+
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+
+ if (pack_spu.swap)
+ {
+ return_val = (GLenum) SWAP32(return_val);
+ }
+
+ return return_val;
+}
+
+#ifdef CHROMIUM_THREADSAFE
+GLint PACKSPU_APIENTRY packspu_VBoxPackSetInjectThread(struct VBOXUHGSMI *pHgsmi)
+{
+ GLint con = 0;
+ int i;
+ GET_THREAD(thread);
+ CRASSERT(!thread);
+ RT_NOREF(pHgsmi);
+ crLockMutex(&_PackMutex);
+ {
+ CRASSERT(CRPACKSPU_IS_WDDM_CRHGSMI() || (pack_spu.numThreads>0));
+ CRASSERT(pack_spu.numThreads<MAX_THREADS);
+ for (i=0; i<MAX_THREADS; ++i)
+ {
+ if (!pack_spu.thread[i].inUse)
+ {
+ thread = &pack_spu.thread[i];
+ break;
+ }
+ }
+ CRASSERT(thread);
+
+ thread->inUse = GL_TRUE;
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI())
+ thread->id = crThreadID();
+ else
+ thread->id = THREAD_OFFSET_MAGIC + i;
+ thread->currentContext = NULL;
+ thread->bInjectThread = GL_TRUE;
+
+ thread->netServer.name = crStrdup(pack_spu.name);
+ thread->netServer.buffer_size = 64 * 1024;
+
+ packspuConnectToServer(&(thread->netServer)
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , pHgsmi
+#endif
+ );
+ CRASSERT(thread->netServer.conn);
+
+ CRASSERT(thread->packer == NULL);
+ thread->packer = crPackNewContext( pack_spu.swap );
+ CRASSERT(thread->packer);
+ crPackInitBuffer(&(thread->buffer), crNetAlloc(thread->netServer.conn),
+ thread->netServer.conn->buffer_size, thread->netServer.conn->mtu);
+ thread->buffer.canBarf = thread->netServer.conn->Barf ? GL_TRUE : GL_FALSE;
+
+ crPackSetBuffer( thread->packer, &thread->buffer );
+ crPackFlushFunc( thread->packer, packspuFlush );
+ crPackFlushArg( thread->packer, (void *) thread );
+ crPackSendHugeFunc( thread->packer, packspuHuge );
+ crPackSetContext( thread->packer );
+
+ crSetTSD(&_PackTSD, thread);
+
+ pack_spu.numThreads++;
+ }
+ crUnlockMutex(&_PackMutex);
+
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ CRASSERT(thread->id - THREAD_OFFSET_MAGIC < RT_ELEMENTS(pack_spu.thread)
+ && GET_THREAD_VAL_ID(thread->id) == thread);
+ con = thread->id;
+ }
+ return con;
+}
+
+GLuint PACKSPU_APIENTRY packspu_VBoxPackGetInjectID(GLint con)
+{
+ GLuint ret;
+
+ crLockMutex(&_PackMutex);
+ {
+ ThreadInfo *thread = NULL;
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ if (!con)
+ {
+ crError("connection expected!");
+ return 0;
+ }
+ thread = GET_THREAD_VAL_ID(con);
+ }
+ else
+ {
+ CRASSERT(!con);
+ thread = GET_THREAD_VAL();
+ }
+ CRASSERT(thread && thread->netServer.conn && thread->netServer.conn->type==CR_VBOXHGCM);
+ ret = thread->netServer.conn->u32ClientID;
+ }
+ crUnlockMutex(&_PackMutex);
+
+ return ret;
+}
+
+void PACKSPU_APIENTRY packspu_VBoxPackSetInjectID(GLuint id)
+{
+ crLockMutex(&_PackMutex);
+ {
+ GET_THREAD(thread);
+
+ CRASSERT(thread && thread->netServer.conn && thread->netServer.conn->type==CR_VBOXHGCM && thread->bInjectThread);
+ thread->netServer.conn->u32InjectClientID = id;
+ }
+ crUnlockMutex(&_PackMutex);
+}
+
+void PACKSPU_APIENTRY packspu_VBoxAttachThread()
+{
+#if 0
+ int i;
+ GET_THREAD(thread);
+
+ for (i=0; i<MAX_THREADS; ++i)
+ {
+ if (pack_spu.thread[i].inUse && thread==&pack_spu.thread[i] && thread->id==crThreadID())
+ {
+ crError("2nd attach to same thread");
+ }
+ }
+#endif
+
+ crSetTSD(&_PackTSD, NULL);
+
+ crStateVBoxAttachThread();
+}
+
+void PACKSPU_APIENTRY packspu_VBoxDetachThread()
+{
+ if (CRPACKSPU_IS_WDDM_CRHGSMI())
+ {
+ crPackSetContext(NULL);
+ crSetTSD(&_PackTSD, NULL);
+ }
+ else
+ {
+ int i;
+ GET_THREAD(thread);
+ if (thread)
+ {
+ crLockMutex(&_PackMutex);
+
+ for (i=0; i<MAX_THREADS; ++i)
+ {
+ if (pack_spu.thread[i].inUse && thread==&pack_spu.thread[i]
+ && thread->id==crThreadID() && thread->netServer.conn)
+ {
+ CRASSERT(pack_spu.numThreads>0);
+
+ packspuFlush((void *) thread);
+
+ if (pack_spu.thread[i].packer)
+ {
+ CR_LOCK_PACKER_CONTEXT(thread->packer);
+ crPackSetContext(NULL);
+ CR_UNLOCK_PACKER_CONTEXT(thread->packer);
+ crPackDeleteContext(pack_spu.thread[i].packer);
+
+ if (pack_spu.thread[i].buffer.pack)
+ {
+ crNetFree(pack_spu.thread[i].netServer.conn, pack_spu.thread[i].buffer.pack);
+ pack_spu.thread[i].buffer.pack = NULL;
+ }
+ }
+ crNetFreeConnection(pack_spu.thread[i].netServer.conn);
+
+ if (pack_spu.thread[i].netServer.name)
+ crFree(pack_spu.thread[i].netServer.name);
+
+ pack_spu.numThreads--;
+ /*note can't shift the array here, because other threads have TLS references to array elements*/
+ crMemZero(&pack_spu.thread[i], sizeof(ThreadInfo));
+
+ crSetTSD(&_PackTSD, NULL);
+
+ if (i==pack_spu.idxThreadInUse)
+ {
+ for (i=0; i<MAX_THREADS; ++i)
+ {
+ if (pack_spu.thread[i].inUse)
+ {
+ pack_spu.idxThreadInUse=i;
+ break;
+ }
+ }
+ }
+
+ break;
+ }
+ }
+
+ for (i=0; i<CR_MAX_CONTEXTS; ++i)
+ {
+ ContextInfo *ctx = &pack_spu.context[i];
+ if (ctx->currentThread == thread)
+ {
+ CRASSERT(ctx->fAutoFlush);
+ ctx->currentThread = NULL;
+ }
+ }
+
+ crUnlockMutex(&_PackMutex);
+ }
+ }
+
+ crStateVBoxDetachThread();
+}
+
+#ifdef WINDOWS
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+BOOL WINAPI DllMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved)
+{
+ (void) lpvReserved;
+
+ switch (fdwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ {
+ crInitMutex(&_PackMutex);
+ break;
+ }
+
+ case DLL_PROCESS_DETACH:
+ {
+ crFreeMutex(&_PackMutex);
+ crNetTearDown();
+ break;
+ }
+
+ case DLL_THREAD_ATTACH:
+ case DLL_THREAD_DETACH:
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+#endif
+
+#else /*ifdef CHROMIUM_THREADSAFE*/
+GLint PACKSPU_APIENTRY packspu_VBoxPackSetInjectThread(struct VBOXUHGSMI *pHgsmi)
+{
+}
+
+GLuint PACKSPU_APIENTRY packspu_VBoxPackGetInjectID(GLint con)
+{
+ return 0;
+}
+
+void PACKSPU_APIENTRY packspu_VBoxPackSetInjectID(GLuint id)
+{
+ (void) id;
+}
+
+void PACKSPU_APIENTRY packspu_VBoxPackAttachThread()
+{
+}
+
+void PACKSPU_APIENTRY packspu_VBoxPackDetachThread()
+{
+}
+#endif /*CHROMIUM_THREADSAFE*/
+
+void PACKSPU_APIENTRY packspu_VBoxPresentComposition(GLint win, const struct VBOXVR_SCR_COMPOSITOR * pCompositor,
+ const struct VBOXVR_SCR_COMPOSITOR_ENTRY *pChangedEntry)
+{
+ RT_NOREF(win, pCompositor, pChangedEntry);
+}
+
+void PACKSPU_APIENTRY packspu_StringMarkerGREMEDY(GLsizei len, const GLvoid *string)
+{
+ RT_NOREF(len, string);
+}
+
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_net.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_net.c
new file mode 100644
index 00000000..6d5d41d6
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_net.c
@@ -0,0 +1,284 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "cr_pack.h"
+#include "cr_mem.h"
+#include "cr_net.h"
+#include "cr_pixeldata.h"
+#include "cr_protocol.h"
+#include "cr_error.h"
+#include "packspu.h"
+#include "packspu_proto.h"
+
+uint32_t g_u32VBoxHostCaps = 0;
+
+static void
+packspuWriteback( const CRMessageWriteback *wb )
+{
+ int *writeback;
+ crMemcpy( &writeback, &(wb->writeback_ptr), sizeof( writeback ) );
+ *writeback = 0;
+}
+
+/**
+ * XXX Note that this routine is identical to crNetRecvReadback except
+ * we set *writeback=0 instead of decrementing it. Hmmm.
+ */
+static void
+packspuReadback( const CRMessageReadback *rb, unsigned int len )
+{
+ /* minus the header, the destination pointer,
+ * *and* the implicit writeback pointer at the head. */
+
+ int payload_len = len - sizeof( *rb );
+ int *writeback;
+ void *dest_ptr;
+ crMemcpy( &writeback, &(rb->writeback_ptr), sizeof( writeback ) );
+ crMemcpy( &dest_ptr, &(rb->readback_ptr), sizeof( dest_ptr ) );
+
+ *writeback = 0;
+ crMemcpy( dest_ptr, ((char *)rb) + sizeof(*rb), payload_len );
+}
+
+static void
+packspuReadPixels( const CRMessageReadPixels *rp, unsigned int len )
+{
+ crNetRecvReadPixels( rp, len );
+ --pack_spu.ReadPixels;
+}
+
+static int
+packspuReceiveData( CRConnection *conn, CRMessage *msg, unsigned int len )
+{
+ RT_NOREF(conn);
+ if (msg->header.type == CR_MESSAGE_REDIR_PTR)
+ msg = (CRMessage*) msg->redirptr.pMessage;
+
+ switch( msg->header.type )
+ {
+ case CR_MESSAGE_READ_PIXELS:
+ packspuReadPixels( &(msg->readPixels), len );
+ break;
+ case CR_MESSAGE_WRITEBACK:
+ packspuWriteback( &(msg->writeback) );
+ break;
+ case CR_MESSAGE_READBACK:
+ packspuReadback( &(msg->readback), len );
+ break;
+ default:
+ /*crWarning( "Why is the pack SPU getting a message of type 0x%x?", msg->type ); */
+ return 0; /* NOT HANDLED */
+ }
+ return 1; /* HANDLED */
+}
+
+static CRMessageOpcodes *
+__prependHeader( CRPackBuffer *buf, unsigned int *len, unsigned int senderID )
+{
+ int num_opcodes;
+ CRMessageOpcodes *hdr;
+ RT_NOREF(senderID);
+
+ CRASSERT( buf );
+ CRASSERT( buf->opcode_current < buf->opcode_start );
+ CRASSERT( buf->opcode_current >= buf->opcode_end );
+ CRASSERT( buf->data_current > buf->data_start );
+ CRASSERT( buf->data_current <= buf->data_end );
+
+ num_opcodes = buf->opcode_start - buf->opcode_current;
+ hdr = (CRMessageOpcodes *)
+ ( buf->data_start - ( ( num_opcodes + 3 ) & ~0x3 ) - sizeof(*hdr) );
+
+ CRASSERT( (void *) hdr >= buf->pack );
+
+ if (pack_spu.swap)
+ {
+ hdr->header.type = (CRMessageType) SWAP32(CR_MESSAGE_OPCODES);
+ hdr->numOpcodes = SWAP32(num_opcodes);
+ }
+ else
+ {
+ hdr->header.type = CR_MESSAGE_OPCODES;
+ hdr->numOpcodes = num_opcodes;
+ }
+
+ *len = buf->data_current - (unsigned char *) hdr;
+
+ return hdr;
+}
+
+
+/*
+ * This is called from either the Pack SPU and the packer library whenever
+ * we need to send a data buffer to the server.
+ */
+void packspuFlush(void *arg )
+{
+ ThreadInfo *thread = (ThreadInfo *) arg;
+ ContextInfo *ctx;
+ unsigned int len;
+ CRMessageOpcodes *hdr;
+ CRPackBuffer *buf;
+
+ /* we should _always_ pass a valid <arg> value */
+ CRASSERT(thread && thread->inUse);
+#ifdef CHROMIUM_THREADSAFE
+ CR_LOCK_PACKER_CONTEXT(thread->packer);
+#endif
+ ctx = thread->currentContext;
+ buf = &(thread->buffer);
+ CRASSERT(buf);
+
+ if (ctx && ctx->fCheckZerroVertAttr)
+ crStateCurrentRecoverNew(ctx->clientState, &thread->packer->current);
+
+ /* We're done packing into the current buffer, unbind it */
+ crPackReleaseBuffer( thread->packer );
+
+ /*
+ printf("%s thread=%p thread->id = %d thread->pc=%p t2->id=%d t2->pc=%p packbuf=%p packbuf=%p\n",
+ __FUNCTION__, (void*) thread, (int) thread->id, thread->packer,
+ (int) t2->id, t2->packer,
+ buf->pack, thread->packer->buffer.pack);
+ */
+
+ if ( buf->opcode_current == buf->opcode_start ) {
+ /*
+ printf("%s early return\n", __FUNCTION__);
+ */
+ /* XXX these calls seem to help, but might be appropriate */
+ crPackSetBuffer( thread->packer, buf );
+ crPackResetPointers(thread->packer);
+#ifdef CHROMIUM_THREADSAFE
+ CR_UNLOCK_PACKER_CONTEXT(thread->packer);
+#endif
+ return;
+ }
+
+ hdr = __prependHeader( buf, &len, 0 );
+
+ CRASSERT( thread->netServer.conn );
+
+ if ( buf->holds_BeginEnd )
+ {
+ /*crDebug("crNetBarf %d, (%d)", len, buf->size);*/
+ crNetBarf( thread->netServer.conn, &(buf->pack), hdr, len );
+ }
+ else
+ {
+ /*crDebug("crNetSend %d, (%d)", len, buf->size);*/
+ crNetSend( thread->netServer.conn, &(buf->pack), hdr, len );
+ }
+
+ buf->pack = crNetAlloc( thread->netServer.conn );
+
+ /* The network may have found a new mtu */
+ buf->mtu = thread->netServer.conn->mtu;
+
+ crPackSetBuffer( thread->packer, buf );
+
+ crPackResetPointers(thread->packer);
+
+#ifdef CHROMIUM_THREADSAFE
+ CR_UNLOCK_PACKER_CONTEXT(thread->packer);
+#endif
+}
+
+
+/**
+ * XXX NOTE: there's a lot of duplicate code here common to the
+ * pack, tilesort and replicate SPUs. Try to simplify someday!
+ */
+void packspuHuge( CROpcode opcode, void *buf )
+{
+ GET_THREAD(thread);
+ unsigned int len;
+ unsigned char *src;
+ CRMessageOpcodes *msg;
+
+ CRASSERT(thread);
+
+ /* packet length is indicated by the variable length field, and
+ includes an additional word for the opcode (with alignment) and
+ a header */
+ len = ((unsigned int *) buf)[-1];
+ if (pack_spu.swap)
+ {
+ /* It's already been swapped, swap it back. */
+ len = SWAP32(len);
+ }
+ len += 4 + sizeof(CRMessageOpcodes);
+
+ /* write the opcode in just before the length */
+ ((unsigned char *) buf)[-5] = (unsigned char) opcode;
+
+ /* fix up the pointer to the packet to include the length & opcode
+ & header */
+ src = (unsigned char *) buf - 8 - sizeof(CRMessageOpcodes);
+
+ msg = (CRMessageOpcodes *) src;
+
+ if (pack_spu.swap)
+ {
+ msg->header.type = (CRMessageType) SWAP32(CR_MESSAGE_OPCODES);
+ msg->numOpcodes = SWAP32(1);
+ }
+ else
+ {
+ msg->header.type = CR_MESSAGE_OPCODES;
+ msg->numOpcodes = 1;
+ }
+
+ CRASSERT( thread->netServer.conn );
+ crNetSend( thread->netServer.conn, NULL, src, len );
+}
+
+static void packspuFirstConnectToServer( CRNetServer *server
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , struct VBOXUHGSMI *pHgsmi
+#endif
+ )
+{
+ crNetInit( packspuReceiveData, NULL );
+ crNetServerConnect( server
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , pHgsmi
+#endif
+ );
+ if (server->conn)
+ {
+ g_u32VBoxHostCaps = crNetHostCapsGet();
+ crPackCapsSet(g_u32VBoxHostCaps);
+ }
+}
+
+void packspuConnectToServer( CRNetServer *server
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , struct VBOXUHGSMI *pHgsmi
+#endif
+ )
+{
+ if (pack_spu.numThreads == 0) {
+ packspuFirstConnectToServer( server
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , pHgsmi
+#endif
+ );
+ if (!server->conn) {
+ crError("packspuConnectToServer: no connection on first create!");
+ return;
+ }
+ pack_spu.swap = server->conn->swap;
+ }
+ else {
+ /* a new pthread */
+ crNetNewClient(server
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , pHgsmi
+#endif
+ );
+ }
+}
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_pixel.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_pixel.c
new file mode 100644
index 00000000..06734b1e
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_pixel.c
@@ -0,0 +1,727 @@
+/* Copyright (c) 2001, Stanford University
+ All rights reserved.
+
+ See the file LICENSE.txt for information on redistributing this software. */
+
+#include "cr_packfunctions.h"
+#include "cr_glstate.h"
+#include "cr_pixeldata.h"
+#include "cr_version.h"
+#include "packspu.h"
+#include "packspu_proto.h"
+
+static GLboolean packspu_CheckTexImageFormat(GLenum format)
+{
+ if (format!=GL_COLOR_INDEX
+ && format!=GL_RED
+ && format!=GL_GREEN
+ && format!=GL_BLUE
+ && format!=GL_ALPHA
+ && format!=GL_RGB
+ && format!=GL_BGR
+ && format!=GL_RGBA
+ && format!=GL_BGRA
+ && format!=GL_LUMINANCE
+ && format!=GL_LUMINANCE_ALPHA
+ && format!=GL_DEPTH_COMPONENT
+ && format!=GL_DEPTH_STENCIL)
+ {
+ /*crWarning("crPackCheckTexImageFormat FAILED format 0x%x isn't valid", format);*/
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+static GLboolean packspu_CheckTexImageType(GLenum type)
+{
+ if (type!=GL_UNSIGNED_BYTE
+ && type!=GL_BYTE
+ && type!=GL_BITMAP
+ && type!=GL_UNSIGNED_SHORT
+ && type!=GL_SHORT
+ && type!=GL_UNSIGNED_INT
+ && type!=GL_INT
+ && type!=GL_FLOAT
+ && type!=GL_UNSIGNED_BYTE_3_3_2
+ && type!=GL_UNSIGNED_BYTE_2_3_3_REV
+ && type!=GL_UNSIGNED_SHORT_5_6_5
+ && type!=GL_UNSIGNED_SHORT_5_6_5_REV
+ && type!=GL_UNSIGNED_SHORT_4_4_4_4
+ && type!=GL_UNSIGNED_SHORT_4_4_4_4_REV
+ && type!=GL_UNSIGNED_SHORT_5_5_5_1
+ && type!=GL_UNSIGNED_SHORT_1_5_5_5_REV
+ && type!=GL_UNSIGNED_INT_8_8_8_8
+ && type!=GL_UNSIGNED_INT_8_8_8_8_REV
+ && type!=GL_UNSIGNED_INT_10_10_10_2
+ && type!=GL_UNSIGNED_INT_2_10_10_10_REV
+ && type!=GL_UNSIGNED_INT_24_8)
+ {
+ /*crWarning("crPackCheckTexImageType FAILED type 0x%x isn't valid", type);*/
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+static GLboolean packspu_CheckTexImageInternalFormat(GLint internalformat)
+{
+ if (internalformat!=1
+ && internalformat!=2
+ && internalformat!=3
+ && internalformat!=4
+ && internalformat!=GL_ALPHA
+ && internalformat!=GL_ALPHA4
+ && internalformat!=GL_ALPHA8
+ && internalformat!=GL_ALPHA12
+ && internalformat!=GL_ALPHA16
+ && internalformat!=GL_COMPRESSED_ALPHA
+ && internalformat!=GL_COMPRESSED_LUMINANCE
+ && internalformat!=GL_COMPRESSED_LUMINANCE_ALPHA
+ && internalformat!=GL_COMPRESSED_INTENSITY
+ && internalformat!=GL_COMPRESSED_RGB
+ && internalformat!=GL_COMPRESSED_RGBA
+ && internalformat!=GL_DEPTH_COMPONENT
+ && internalformat!=GL_DEPTH_COMPONENT16
+ && internalformat!=GL_DEPTH_COMPONENT24
+ && internalformat!=GL_DEPTH_COMPONENT32
+ && internalformat!=GL_DEPTH24_STENCIL8
+ && internalformat!=GL_LUMINANCE
+ && internalformat!=GL_LUMINANCE4
+ && internalformat!=GL_LUMINANCE8
+ && internalformat!=GL_LUMINANCE12
+ && internalformat!=GL_LUMINANCE16
+ && internalformat!=GL_LUMINANCE_ALPHA
+ && internalformat!=GL_LUMINANCE4_ALPHA4
+ && internalformat!=GL_LUMINANCE6_ALPHA2
+ && internalformat!=GL_LUMINANCE8_ALPHA8
+ && internalformat!=GL_LUMINANCE12_ALPHA4
+ && internalformat!=GL_LUMINANCE12_ALPHA12
+ && internalformat!=GL_LUMINANCE16_ALPHA16
+ && internalformat!=GL_INTENSITY
+ && internalformat!=GL_INTENSITY4
+ && internalformat!=GL_INTENSITY8
+ && internalformat!=GL_INTENSITY12
+ && internalformat!=GL_INTENSITY16
+ && internalformat!=GL_R3_G3_B2
+ && internalformat!=GL_RGB
+ && internalformat!=GL_RGB4
+ && internalformat!=GL_RGB5
+ && internalformat!=GL_RGB8
+ && internalformat!=GL_RGB10
+ && internalformat!=GL_RGB12
+ && internalformat!=GL_RGB16
+ && internalformat!=GL_RGBA
+ && internalformat!=GL_RGBA2
+ && internalformat!=GL_RGBA4
+ && internalformat!=GL_RGB5_A1
+ && internalformat!=GL_RGBA8
+ && internalformat!=GL_RGB10_A2
+ && internalformat!=GL_RGBA12
+ && internalformat!=GL_RGBA16
+ && internalformat!=GL_SLUMINANCE
+ && internalformat!=GL_SLUMINANCE8
+ && internalformat!=GL_SLUMINANCE_ALPHA
+ && internalformat!=GL_SLUMINANCE8_ALPHA8
+ && internalformat!=GL_SRGB
+ && internalformat!=GL_SRGB8
+ && internalformat!=GL_SRGB_ALPHA
+ && internalformat!=GL_SRGB8_ALPHA8
+#ifdef CR_EXT_texture_compression_s3tc
+ && internalformat!=GL_COMPRESSED_RGB_S3TC_DXT1_EXT
+ && internalformat!=GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
+ && internalformat!=GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
+ && internalformat!=GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
+# ifdef CR_EXT_texture_sRGB
+ && internalformat!=GL_COMPRESSED_SRGB_S3TC_DXT1_EXT
+ && internalformat!=GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT
+ && internalformat!=GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT
+ && internalformat!=GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
+# endif
+#endif
+ /** @todo ARB_texture_float*/
+ && internalformat!=GL_RGBA32F_ARB
+ && internalformat!=GL_RGB32F_ARB
+ && internalformat!=GL_ALPHA32F_ARB
+ && internalformat!=GL_INTENSITY32F_ARB
+ && internalformat!=GL_LUMINANCE32F_ARB
+ && internalformat!=GL_LUMINANCE_ALPHA32F_ARB
+ && internalformat!=GL_RGBA16F_ARB
+ && internalformat!=GL_RGB16F_ARB
+ && internalformat!=GL_ALPHA16F_ARB
+ && internalformat!=GL_INTENSITY16F_ARB
+ && internalformat!=GL_LUMINANCE16F_ARB
+ && internalformat!=GL_LUMINANCE_ALPHA16F_ARB
+ )
+ {
+ /*crWarning("crPackCheckTexImageInternalFormat FAILED internalformat 0x%x isn't valid", internalformat);*/
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+static GLboolean packspu_CheckTexImageParams(GLint internalformat, GLenum format, GLenum type)
+{
+ return packspu_CheckTexImageFormat(format)
+ && packspu_CheckTexImageType(type)
+ && packspu_CheckTexImageInternalFormat(internalformat);
+}
+
+static GLboolean packspu_CheckTexImageFormatType(GLenum format, GLenum type)
+{
+ return packspu_CheckTexImageFormat(format)
+ && packspu_CheckTexImageType(type);
+}
+
+static const CRPixelPackState _defaultPacking = {
+ 0, /* rowLength */
+ 0, /* skipRows */
+ 0, /* skipPixels */
+ 1, /* alignment */
+ 0, /* imageHeight */
+ 0, /* skipImages */
+ GL_FALSE, /* swapBytes */
+ GL_FALSE, /* psLSBFirst */
+};
+
+#define APPLY_IF_NEQ(state, field, enum) \
+ if (state.field != _defaultPacking.field) \
+ { \
+ crPackPixelStorei(enum, state.field); \
+ }
+
+#define RESTORE_IF_NEQ(state, field, enum) \
+ if (state.field != _defaultPacking.field) \
+ { \
+ crPackPixelStorei(enum, _defaultPacking.field); \
+ }
+
+static void packspu_ApplyUnpackState(void)
+{
+ GET_THREAD(thread);
+ ContextInfo *ctx = thread->currentContext;
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ APPLY_IF_NEQ(clientState->unpack, rowLength, GL_UNPACK_ROW_LENGTH);
+ APPLY_IF_NEQ(clientState->unpack, skipRows, GL_UNPACK_SKIP_ROWS);
+ APPLY_IF_NEQ(clientState->unpack, skipPixels, GL_UNPACK_SKIP_PIXELS);
+ APPLY_IF_NEQ(clientState->unpack, alignment, GL_UNPACK_ALIGNMENT);
+ APPLY_IF_NEQ(clientState->unpack, imageHeight, GL_UNPACK_IMAGE_HEIGHT);
+ APPLY_IF_NEQ(clientState->unpack, skipImages, GL_UNPACK_SKIP_IMAGES);
+ APPLY_IF_NEQ(clientState->unpack, swapBytes, GL_UNPACK_SWAP_BYTES);
+ APPLY_IF_NEQ(clientState->unpack, psLSBFirst, GL_UNPACK_LSB_FIRST);
+}
+
+static void packspu_RestoreUnpackState(void)
+{
+ GET_THREAD(thread);
+ ContextInfo *ctx = thread->currentContext;
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ RESTORE_IF_NEQ(clientState->unpack, rowLength, GL_UNPACK_ROW_LENGTH);
+ RESTORE_IF_NEQ(clientState->unpack, skipRows, GL_UNPACK_SKIP_ROWS);
+ RESTORE_IF_NEQ(clientState->unpack, skipPixels, GL_UNPACK_SKIP_PIXELS);
+ RESTORE_IF_NEQ(clientState->unpack, alignment, GL_UNPACK_ALIGNMENT);
+ RESTORE_IF_NEQ(clientState->unpack, imageHeight, GL_UNPACK_IMAGE_HEIGHT);
+ RESTORE_IF_NEQ(clientState->unpack, skipImages, GL_UNPACK_SKIP_IMAGES);
+ RESTORE_IF_NEQ(clientState->unpack, swapBytes, GL_UNPACK_SWAP_BYTES);
+ RESTORE_IF_NEQ(clientState->unpack, psLSBFirst, GL_UNPACK_LSB_FIRST);
+}
+
+static void packspu_ApplyPackState(void)
+{
+ GET_THREAD(thread);
+ ContextInfo *ctx = thread->currentContext;
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ APPLY_IF_NEQ(clientState->pack, rowLength, GL_PACK_ROW_LENGTH);
+ APPLY_IF_NEQ(clientState->pack, skipRows, GL_PACK_SKIP_ROWS);
+ APPLY_IF_NEQ(clientState->pack, skipPixels, GL_PACK_SKIP_PIXELS);
+ APPLY_IF_NEQ(clientState->pack, alignment, GL_PACK_ALIGNMENT);
+ APPLY_IF_NEQ(clientState->pack, imageHeight, GL_PACK_IMAGE_HEIGHT);
+ APPLY_IF_NEQ(clientState->pack, skipImages, GL_PACK_SKIP_IMAGES);
+ APPLY_IF_NEQ(clientState->pack, swapBytes, GL_PACK_SWAP_BYTES);
+ APPLY_IF_NEQ(clientState->pack, psLSBFirst, GL_PACK_LSB_FIRST);
+}
+
+static void packspu_RestorePackState(void)
+{
+ GET_THREAD(thread);
+ ContextInfo *ctx = thread->currentContext;
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ RESTORE_IF_NEQ(clientState->pack, rowLength, GL_PACK_ROW_LENGTH);
+ RESTORE_IF_NEQ(clientState->pack, skipRows, GL_PACK_SKIP_ROWS);
+ RESTORE_IF_NEQ(clientState->pack, skipPixels, GL_PACK_SKIP_PIXELS);
+ RESTORE_IF_NEQ(clientState->pack, alignment, GL_PACK_ALIGNMENT);
+ RESTORE_IF_NEQ(clientState->pack, imageHeight, GL_PACK_IMAGE_HEIGHT);
+ RESTORE_IF_NEQ(clientState->pack, skipImages, GL_PACK_SKIP_IMAGES);
+ RESTORE_IF_NEQ(clientState->pack, swapBytes, GL_PACK_SWAP_BYTES);
+ RESTORE_IF_NEQ(clientState->pack, psLSBFirst, GL_PACK_LSB_FIRST);
+}
+
+void PACKSPU_APIENTRY packspu_PixelStoref( GLenum pname, GLfloat param )
+{
+ /* NOTE: we do not send pixel store parameters to the server!
+ * When we pack a glDrawPixels or glTexImage2D image we interpret
+ * the user's pixel store parameters at that time and pack the
+ * image in a canonical layout (see util/pixel.c).
+ */
+ crStatePixelStoref( pname, param );
+}
+
+void PACKSPU_APIENTRY packspu_PixelStorei( GLenum pname, GLint param )
+{
+ crStatePixelStorei( pname, param );
+}
+
+void PACKSPU_APIENTRY packspu_DrawPixels( GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels )
+{
+ GET_THREAD(thread);
+ ContextInfo *ctx = thread->currentContext;
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ crPackDrawPixels( width, height, format, type, pixels, &(clientState->unpack) );
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+
+void PACKSPU_APIENTRY packspu_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels )
+{
+ GET_THREAD(thread);
+ ContextInfo *ctx = thread->currentContext;
+ CRClientState *clientState = &(ctx->clientState->client);
+ int writeback;
+
+ if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+ {
+ packspu_ApplyPackState();
+ }
+
+ crPackReadPixels(x, y, width, height, format, type, pixels, &(clientState->pack), &writeback);
+
+ if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+ {
+ packspu_RestorePackState();
+ }
+
+#ifdef CR_ARB_pixel_buffer_object
+ if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+#endif
+ {
+ pack_spu.ReadPixels++;
+
+ packspuFlush((void *) thread);
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ }
+}
+
+/** @todo check with pbo's*/
+void PACKSPU_APIENTRY packspu_CopyPixels( GLint x, GLint y, GLsizei width, GLsizei height, GLenum type )
+{
+ GET_THREAD(thread);
+ if (pack_spu.swap)
+ crPackCopyPixelsSWAP( x, y, width, height, type );
+ else
+ crPackCopyPixels( x, y, width, height, type );
+ /* XXX why flush here? */
+ packspuFlush( (void *) thread );
+}
+
+void PACKSPU_APIENTRY packspu_Bitmap( GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap )
+{
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ crPackBitmap(width, height, xorig, yorig, xmove, ymove, bitmap, &(clientState->unpack));
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+
+void PACKSPU_APIENTRY packspu_TexImage1D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels )
+{
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ if (!packspu_CheckTexImageParams(internalformat, format, type))
+ {
+ if (pixels || crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ crWarning("packspu_TexImage1D invalid internalFormat(%x)/format(%x)/type(%x)", internalformat, format, type);
+ return;
+ }
+ internalformat = packspu_CheckTexImageInternalFormat(internalformat) ? internalformat:GL_RGBA;
+ format = packspu_CheckTexImageFormat(format) ? format:GL_RGBA;
+ type = packspu_CheckTexImageType(type) ? type:GL_UNSIGNED_BYTE;
+ }
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ if (pack_spu.swap)
+ crPackTexImage1DSWAP( target, level, internalformat, width, border, format, type, pixels, &(clientState->unpack) );
+ else
+ crPackTexImage1D( target, level, internalformat, width, border, format, type, pixels, &(clientState->unpack) );
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+
+void PACKSPU_APIENTRY packspu_TexImage2D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels )
+{
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ if (!packspu_CheckTexImageParams(internalformat, format, type))
+ {
+ if (pixels || crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ crWarning("packspu_TexImage2D invalid internalFormat(%x)/format(%x)/type(%x)", internalformat, format, type);
+ return;
+ }
+ internalformat = packspu_CheckTexImageInternalFormat(internalformat) ? internalformat:GL_RGBA;
+ format = packspu_CheckTexImageFormat(format) ? format:GL_RGBA;
+ type = packspu_CheckTexImageType(type) ? type:GL_UNSIGNED_BYTE;
+ }
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ if (pack_spu.swap)
+ crPackTexImage2DSWAP( target, level, internalformat, width, height, border, format, type, pixels, &(clientState->unpack) );
+ else
+ crPackTexImage2D( target, level, internalformat, width, height, border, format, type, pixels, &(clientState->unpack) );
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+
+#ifdef GL_EXT_texture3D
+void PACKSPU_APIENTRY packspu_TexImage3DEXT( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels )
+{
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ if (pack_spu.swap)
+ crPackTexImage3DEXTSWAP( target, level, internalformat, width, height, depth, border, format, type, pixels, &(clientState->unpack) );
+ else
+ crPackTexImage3DEXT( target, level, internalformat, width, height, depth, border, format, type, pixels, &(clientState->unpack) );
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+#endif
+
+#ifdef CR_OPENGL_VERSION_1_2
+void PACKSPU_APIENTRY packspu_TexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels )
+{
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ if (pack_spu.swap)
+ crPackTexImage3DSWAP( target, level, internalformat, width, height, depth, border, format, type, pixels, &(clientState->unpack) );
+ else
+ crPackTexImage3D( target, level, internalformat, width, height, depth, border, format, type, pixels, &(clientState->unpack) );
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+#endif /* CR_OPENGL_VERSION_1_2 */
+
+void PACKSPU_APIENTRY packspu_TexSubImage1D( GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels )
+{
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ if (!packspu_CheckTexImageFormatType(format, type))
+ {
+ crWarning("packspu_TexSubImage1D invalid format(%x)/type(%x)", format, type);
+ return;
+ }
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ if (pack_spu.swap)
+ crPackTexSubImage1DSWAP( target, level, xoffset, width, format, type, pixels, &(clientState->unpack) );
+ else
+ crPackTexSubImage1D( target, level, xoffset, width, format, type, pixels, &(clientState->unpack) );
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+
+void PACKSPU_APIENTRY packspu_TexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels )
+{
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ if (!packspu_CheckTexImageFormatType(format, type))
+ {
+ crWarning("packspu_TexSubImage2D invalid format(%x)/type(%x)", format, type);
+ return;
+ }
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ if (pack_spu.swap)
+ crPackTexSubImage2DSWAP( target, level, xoffset, yoffset, width, height, format, type, pixels, &(clientState->unpack) );
+ else
+ crPackTexSubImage2D( target, level, xoffset, yoffset, width, height, format, type, pixels, &(clientState->unpack) );
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+
+#ifdef CR_OPENGL_VERSION_1_2
+void PACKSPU_APIENTRY packspu_TexSubImage3D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels )
+{
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ if (pack_spu.swap)
+ crPackTexSubImage3DSWAP( target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels, &(clientState->unpack) );
+ else
+ crPackTexSubImage3D( target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels, &(clientState->unpack) );
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+#endif /* CR_OPENGL_VERSION_1_2 */
+
+void PACKSPU_APIENTRY packspu_ZPixCR( GLsizei width, GLsizei height, GLenum format, GLenum type, GLenum ztype, GLint zparm, GLint length, const GLvoid *pixels )
+{
+ GET_CONTEXT(ctx);
+ CRClientState *clientState = &(ctx->clientState->client);
+ if (pack_spu.swap)
+ crPackZPixCRSWAP( width, height, format, type, ztype, zparm, length, pixels, &(clientState->unpack) );
+ else
+ crPackZPixCR( width, height, format, type, ztype, zparm, length, pixels, &(clientState->unpack) );
+}
+
+void PACKSPU_APIENTRY packspu_GetTexImage (GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels)
+{
+ GET_THREAD(thread);
+ ContextInfo *ctx = thread->currentContext;
+ CRClientState *clientState = &(ctx->clientState->client);
+ int writeback = 1;
+
+ /* XXX note: we're not observing the pixel pack parameters here unless PACK PBO is bound
+ * To do so, we'd have to allocate a temporary image buffer (how large???)
+ * and copy the image to the user's buffer using the pixel pack params.
+ */
+
+ if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+ {
+ packspu_ApplyPackState();
+ }
+
+ if (pack_spu.swap)
+ crPackGetTexImageSWAP( target, level, format, type, pixels, &(clientState->pack), &writeback );
+ else
+ crPackGetTexImage( target, level, format, type, pixels, &(clientState->pack), &writeback );
+
+ if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+ {
+ packspu_RestorePackState();
+ }
+
+#ifdef CR_ARB_pixel_buffer_object
+ if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+#endif
+ {
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ }
+}
+
+void PACKSPU_APIENTRY packspu_GetCompressedTexImageARB( GLenum target, GLint level, GLvoid * img )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+
+ if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+ {
+ packspu_ApplyPackState();
+ }
+
+ if (pack_spu.swap)
+ {
+ crPackGetCompressedTexImageARBSWAP( target, level, img, &writeback );
+ }
+ else
+ {
+ crPackGetCompressedTexImageARB( target, level, img, &writeback );
+ }
+
+ if (crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+ {
+ packspu_RestorePackState();
+ }
+
+#ifdef CR_ARB_pixel_buffer_object
+ if (!crStateIsBufferBound(GL_PIXEL_PACK_BUFFER_ARB))
+#endif
+ {
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ }
+}
+
+void PACKSPU_APIENTRY
+packspu_CompressedTexImage1DARB(GLenum target, GLint level, GLenum internalformat, GLsizei width,
+ GLint border, GLsizei imagesize, const GLvoid *data)
+{
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ crPackCompressedTexImage1DARB(target, level, internalformat, width, border, imagesize, data);
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+
+void PACKSPU_APIENTRY
+packspu_CompressedTexImage2DARB(GLenum target, GLint level, GLenum internalformat, GLsizei width,
+ GLsizei height, GLint border, GLsizei imagesize, const GLvoid *data)
+{
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ crPackCompressedTexImage2DARB(target, level, internalformat, width, height, border, imagesize, data);
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+
+void PACKSPU_APIENTRY
+packspu_CompressedTexImage3DARB(GLenum target, GLint level, GLenum internalformat, GLsizei width,
+ GLsizei height, GLsizei depth, GLint border, GLsizei imagesize, const GLvoid *data)
+{
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ crPackCompressedTexImage3DARB(target, level, internalformat, width, height, depth, border, imagesize, data);
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+
+void PACKSPU_APIENTRY
+packspu_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, GLsizei width,
+ GLenum format, GLsizei imagesize, const GLvoid *data)
+{
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ crPackCompressedTexSubImage1DARB(target, level, xoffset, width, format, imagesize, data);
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+
+void PACKSPU_APIENTRY
+packspu_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height, GLenum format, GLsizei imagesize, const GLvoid *data)
+{
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ crPackCompressedTexSubImage2DARB(target, level, xoffset, yoffset, width, height, format, imagesize, data);
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
+
+void PACKSPU_APIENTRY
+packspu_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+ GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format,
+ GLsizei imagesize, const GLvoid *data)
+{
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_ApplyUnpackState();
+ }
+
+ crPackCompressedTexSubImage3DARB(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imagesize, data);
+
+ if (crStateIsBufferBound(GL_PIXEL_UNPACK_BUFFER_ARB))
+ {
+ packspu_RestoreUnpackState();
+ }
+}
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_proto.py b/src/VBox/Additions/common/crOpenGL/pack/packspu_proto.py
new file mode 100755
index 00000000..5feed9a9
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_proto.py
@@ -0,0 +1,50 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+apiutil.CopyrightC()
+
+print("""
+/* DO NOT EDIT - THIS FILE AUTOMATICALLY GENERATED BY packspu_proto.py SCRIPT */
+
+#ifndef PACKSPU_FUNCTIONS_H
+#define PACKSPU_FUNCTIONS_H 1
+
+#include <stdio.h>
+#include "cr_string.h"
+#include "cr_spu.h"
+#include "packspu.h"
+#include "cr_packfunctions.h"
+""")
+
+
+pack_specials = []
+
+keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+# make list of special functions
+for func_name in keys:
+ if ("get" in apiutil.Properties(func_name) or
+ apiutil.FindSpecial( "packspu", func_name ) or
+ apiutil.FindSpecial( "packspu_flush", func_name ) or
+ apiutil.FindSpecial( "packspu_vertex", func_name )):
+ pack_specials.append( func_name )
+
+for func_name in keys:
+ if apiutil.FindSpecial( "packspu_unimplemented", func_name ):
+ continue
+ if func_name in pack_specials:
+ return_type = apiutil.ReturnType(func_name)
+ params = apiutil.Parameters(func_name)
+ print('extern %s PACKSPU_APIENTRY packspu_%s(%s);' % ( return_type, func_name, apiutil.MakeDeclarationString(params) ))
+
+
+print("""
+#endif
+""")
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_special b/src/VBox/Additions/common/crOpenGL/pack/packspu_special
new file mode 100644
index 00000000..13c3e0a2
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_special
@@ -0,0 +1,138 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+AreTexturesResident
+AreProgramsResidentNV
+GetString
+GetTexImage
+EnableClientState
+DisableClientState
+Enable
+Disable
+ClientActiveTextureARB
+ColorPointer
+FogCoordPointerEXT
+SecondaryColorPointerEXT
+VertexAttribPointerARB
+VertexAttribPointerNV
+GetPointerv
+VertexPointer
+NormalPointer
+TexCoordPointer
+EdgeFlagPointer
+IndexPointer
+ArrayElement
+DrawArrays
+DrawElements
+DrawRangeElements
+InterleavedArrays
+ReadPixels
+DrawPixels
+CopyPixels
+Bitmap
+SwapBuffers
+Flush
+Finish
+PixelStorei
+PixelStoref
+PushClientAttrib
+PopClientAttrib
+CreateContext
+WindowCreate
+MakeCurrent
+DestroyContext
+Begin
+End
+TexImage1D
+TexSubImage1D
+TexImage2D
+TexSubImage2D
+TexImage3D
+TexImage3DEXT
+TexSubImage3D
+ChromiumParametervCR
+MultiDrawArraysEXT
+MultiDrawElementsEXT
+GetBufferPointervARB
+GetBufferParameterivARB
+MapBufferARB
+UnmapBufferARB
+BindBufferARB
+BufferDataARB
+ZPixCR
+ActiveTextureARB
+DrawBuffer
+Flush
+GetActiveAttrib
+GetActiveUniform
+GetAttachedShaders
+GetShaderInfoLog
+GetProgramInfoLog
+GetShaderSource
+GetAttachedObjectsARB
+GetInfoLogARB
+BufferSubDataARB
+EnableVertexAttribArrayARB
+DisableVertexAttribArrayARB
+GetBufferSubDataARB
+IsEnabled
+LockArraysEXT
+UnlockArraysEXT
+CreateProgram
+LinkProgram
+DeleteProgram
+GetUniformLocation
+GetAttribLocation
+GetUniformsLocations
+GetAttribsLocations
+BindFramebufferEXT
+DeleteObjectARB
+BindFramebufferEXT
+DeleteFramebuffersEXT
+FramebufferTexture1DEXT
+FramebufferTexture2DEXT
+FramebufferTexture3DEXT
+FramebufferRenderbufferEXT
+CheckFramebufferStatusEXT
+BindTexture
+DeleteTextures
+GetPolygonStipple
+GetPixelMapfv
+GetPixelMapuiv
+GetPixelMapusv
+GetCompressedTexImageARB
+BindRenderbufferEXT
+VBoxPackSetInjectThread
+VBoxPackGetInjectID
+VBoxPackSetInjectID
+VBoxAttachThread
+VBoxDetachThread
+VBoxCreateContext
+VBoxConChromiumParameteriCR
+VBoxConChromiumParametervCR
+VBoxWindowCreate
+VBoxWindowDestroy
+VBoxConCreate
+VBoxConDestroy
+VBoxConFlush
+VBoxPresentComposition
+ChromiumParameteriCR
+CompressedTexImage1DARB
+CompressedTexImage2DARB
+CompressedTexImage3DARB
+CompressedTexSubImage1DARB
+CompressedTexSubImage2DARB
+CompressedTexSubImage3DARB
+GenFramebuffersEXT
+GenRenderbuffersEXT
+DeleteFramebuffersEXT
+DeleteRenderbuffersEXT
+GenBuffersARB
+DeleteBuffersARB
+StringMarkerGREMEDY
+GenTextures
+CompileShader
+NewList
+EndList
+GetError
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_swapbuf.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_swapbuf.c
new file mode 100644
index 00000000..bc1895fe
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_swapbuf.c
@@ -0,0 +1,102 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "cr_packfunctions.h"
+#include "cr_error.h"
+#include "cr_net.h"
+#include "packspu.h"
+#include "packspu_proto.h"
+
+#if 0
+
+void PACKSPU_APIENTRY packspu_SwapBuffers( GLint window, GLint flags )
+{
+ GET_THREAD(thread);
+ if (pack_spu.swap)
+ {
+ crPackSwapBuffersSWAP( window, flags );
+ }
+ else
+ {
+ crPackSwapBuffers( window, flags );
+ }
+ packspuFlush( (void *) thread );
+}
+
+
+#else
+
+void PACKSPU_APIENTRY packspu_SwapBuffers( GLint window, GLint flags )
+{
+ GET_THREAD(thread);
+
+ if (pack_spu.swap)
+ {
+ crPackSwapBuffersSWAP( window, flags );
+ }
+ else
+ {
+ crPackSwapBuffers( window, flags );
+ }
+ packspuFlush( (void *) thread );
+
+ if (!(thread->netServer.conn->actual_network))
+ {
+ /* no synchronization needed */
+ return;
+ }
+
+ if (pack_spu.swapbuffer_sync) {
+ /* This won't block unless there has been more than 1 frame
+ * since we received a writeback acknowledgement. In the
+ * normal case there's no performance penalty for doing this
+ * (beyond the cost of packing the writeback request into the
+ * stream and receiving the reply), but it eliminates the
+ * problem of runaway rendering that can occur, eg when
+ * rendering frames consisting of a single large display list
+ * in a tight loop.
+ *
+ * Note that this is *not* the same as doing a sync after each
+ * swapbuffers, which would force a round-trip 'bubble' into
+ * the network stream under normal conditions.
+ *
+ * This is complicated because writeback in the pack spu is
+ * overridden to always set the value to zero when the
+ * reply is received, rather than decrementing it:
+ */
+ switch( thread->writeback ) {
+ case 0:
+ /* Request writeback.
+ */
+ thread->writeback = 1;
+ if (pack_spu.swap)
+ {
+ crPackWritebackSWAP( (GLint *) &thread->writeback );
+ }
+ else
+ {
+ crPackWriteback( (GLint *) &thread->writeback );
+ }
+ break;
+ case 1:
+ /* Make sure writeback from previous frame has been received.
+ */
+ CRPACKSPU_WRITEBACK_WAIT(thread, thread->writeback);
+ break;
+ }
+ }
+
+ /* want to emit a parameter here */
+ if (pack_spu.emit_GATHER_POST_SWAPBUFFERS)
+ {
+ if (pack_spu.swap)
+ crPackChromiumParameteriCRSWAP(GL_GATHER_POST_SWAPBUFFERS_CR, 1);
+ else
+ crPackChromiumParameteriCR(GL_GATHER_POST_SWAPBUFFERS_CR, 1);
+ }
+}
+
+#endif
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_texture.c b/src/VBox/Additions/common/crOpenGL/pack/packspu_texture.c
new file mode 100644
index 00000000..5057bcb3
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_texture.c
@@ -0,0 +1,70 @@
+/* $Id: packspu_texture.c $ */
+
+/** @file
+ * VBox OpenGL DRI driver functions
+ */
+
+/*
+ * Copyright (C) 2009-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include "packspu.h"
+#include "cr_packfunctions.h"
+#include "cr_glstate.h"
+#include "packspu_proto.h"
+
+void PACKSPU_APIENTRY packspu_ActiveTextureARB(GLenum texture)
+{
+ crStateActiveTextureARB(texture);
+ crPackActiveTextureARB(texture);
+}
+
+void PACKSPU_APIENTRY packspu_BindTexture(GLenum target, GLuint texture)
+{
+ crStateBindTexture(target, texture);
+ crPackBindTexture(target, texture);
+}
+
+void PACKSPU_APIENTRY packspu_DeleteTextures(GLsizei n, const GLuint * textures)
+{
+ crStateDeleteTextures(n, textures);
+ crPackDeleteTextures(n, textures);
+}
+
+void PACKSPU_APIENTRY packspu_GenTextures( GLsizei n, GLuint * textures )
+{
+ GET_THREAD(thread);
+ int writeback = 1;
+ unsigned int i;
+ if (!CRPACKSPU_IS_WDDM_CRHGSMI() && !(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn->actual_network))
+ {
+ crError( "packspu_GenTextures doesn't work when there's no actual network involved!\nTry using the simplequery SPU in your chain!" );
+ }
+ if (pack_spu.swap)
+ {
+ crPackGenTexturesSWAP( n, textures, &writeback );
+ }
+ else
+ {
+ crPackGenTextures( n, textures, &writeback );
+ }
+ packspuFlush( (void *) thread );
+ CRPACKSPU_WRITEBACK_WAIT(thread, writeback);
+ if (pack_spu.swap)
+ {
+ for (i = 0 ; i < (unsigned int) n ; i++)
+ {
+ textures[i] = SWAP32(textures[i]);
+ }
+ }
+
+ crStateRegTextures(n, textures);
+}
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_unimplemented_special b/src/VBox/Additions/common/crOpenGL/pack/packspu_unimplemented_special
new file mode 100644
index 00000000..f71300c9
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_unimplemented_special
@@ -0,0 +1,4 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
diff --git a/src/VBox/Additions/common/crOpenGL/pack/packspu_vertex_special b/src/VBox/Additions/common/crOpenGL/pack/packspu_vertex_special
new file mode 100644
index 00000000..bbbc13d0
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/pack/packspu_vertex_special
@@ -0,0 +1,28 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+Vertex2d
+Vertex2dv
+Vertex2f
+Vertex2fv
+Vertex2i
+Vertex2iv
+Vertex2s
+Vertex2sv
+Vertex3d
+Vertex3dv
+Vertex3f
+Vertex3fv
+Vertex3i
+Vertex3iv
+Vertex3s
+Vertex3sv
+Vertex4d
+Vertex4dv
+Vertex4f
+Vertex4fv
+Vertex4i
+Vertex4iv
+Vertex4s
+Vertex4sv
diff --git a/src/VBox/Additions/common/crOpenGL/passthrough/Makefile.kup b/src/VBox/Additions/common/crOpenGL/passthrough/Makefile.kup
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/passthrough/Makefile.kup
diff --git a/src/VBox/Additions/common/crOpenGL/passthrough/passthrough.def b/src/VBox/Additions/common/crOpenGL/passthrough/passthrough.def
new file mode 100644
index 00000000..9edc7163
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/passthrough/passthrough.def
@@ -0,0 +1,6 @@
+; Copyright (c) 2001, Stanford University
+; All rights reserved.
+;
+; See the file LICENSE.txt for information on redistributing this software.
+EXPORTS
+SPULoad
diff --git a/src/VBox/Additions/common/crOpenGL/passthrough/passthrough.py b/src/VBox/Additions/common/crOpenGL/passthrough/passthrough.py
new file mode 100755
index 00000000..ec7e27c7
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/passthrough/passthrough.py
@@ -0,0 +1,40 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+
+apiutil.CopyrightC()
+
+print("""#include <stdio.h>
+#include "cr_error.h"
+#include "cr_string.h"
+#include "cr_spu.h"
+#include "passthroughspu.h"
+""")
+
+keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+
+print('SPUNamedFunctionTable _cr_passthrough_table[%d];' % ( len(keys) + 1 ))
+
+print("""
+static void __fillin(int offset, char *name, SPUGenericFunction func)
+{
+ _cr_passthrough_table[offset].name = crStrdup(name);
+ _cr_passthrough_table[offset].fn = func;
+}
+
+void BuildPassthroughTable( SPU *child )
+{""")
+
+for index in range(len(keys)):
+ func_name = keys[index]
+ print('\t__fillin(%3d, "%s", (SPUGenericFunction) child->dispatch_table.%s);' % (index, func_name, func_name ))
+print('\t__fillin(%3d, NULL, NULL);' % len(keys))
+print('}')
diff --git a/src/VBox/Additions/common/crOpenGL/passthrough/passthroughspu.h b/src/VBox/Additions/common/crOpenGL/passthrough/passthroughspu.h
new file mode 100644
index 00000000..a0e6b942
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/passthrough/passthroughspu.h
@@ -0,0 +1,21 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#ifndef GA_INCLUDED_SRC_common_crOpenGL_passthrough_passthroughspu_h
+#define GA_INCLUDED_SRC_common_crOpenGL_passthrough_passthroughspu_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+
+#include "cr_spu.h"
+
+
+extern SPUNamedFunctionTable _cr_passthrough_table[];
+extern void BuildPassthroughTable( SPU *child );
+
+
+#endif /* !GA_INCLUDED_SRC_common_crOpenGL_passthrough_passthroughspu_h */
diff --git a/src/VBox/Additions/common/crOpenGL/passthrough/passthroughspu.rc b/src/VBox/Additions/common/crOpenGL/passthrough/passthroughspu.rc
new file mode 100644
index 00000000..ad2034e5
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/passthrough/passthroughspu.rc
@@ -0,0 +1,69 @@
+/* $Id: passthroughspu.rc $ */
+/** @file
+ * VBoxOGLpassthroughspu - Resource file containing version info and icon.
+ */
+
+/*
+ * Copyright (C) 2009-2019 Oracle Corporation
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#include <windows.h>
+#include <VBox/version.h>
+
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION VBOX_RC_FILE_VERSION
+ PRODUCTVERSION VBOX_RC_FILE_VERSION
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS VBOX_RC_FILE_FLAGS
+ FILEOS VBOX_RC_FILE_OS
+ FILETYPE VBOX_RC_TYPE_DRV
+ FILESUBTYPE VFT2_DRV_DISPLAY
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "FileDescription", "VirtualBox crOpenGL ICD\0"
+ VALUE "InternalName", "VBoxOGLpassthroughspu\0"
+#ifdef VBOX_WDDM_WOW64
+ VALUE "OriginalFilename", "VBoxOGLpassthroughspu-x86.dll\0"
+#else
+ VALUE "OriginalFilename", "VBoxOGLpassthroughspu.dll\0"
+#endif
+ VALUE "CompanyName", VBOX_RC_COMPANY_NAME
+ VALUE "FileVersion", VBOX_RC_FILE_VERSION_STR
+ VALUE "LegalCopyright", VBOX_RC_LEGAL_COPYRIGHT
+ VALUE "ProductName", VBOX_RC_PRODUCT_NAME_GA_STR
+ VALUE "ProductVersion", VBOX_RC_PRODUCT_VERSION_STR
+ VBOX_RC_MORE_STRINGS
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+1 RCDATA
+BEGIN
+// Machine dependent parameters
+ 17, // Height of vertical thumb
+ 17, // Width of horizontal thumb
+ 2, // Icon horiz compression factor
+ 2, // Icon vert compression factor
+ 1, // Cursor horz compression factor
+ 1, // Cursor vert compression factor
+ 0, // Kanji window height
+ 1, // cxBorder (thickness of vertical lines)
+ 1 // cyBorder (thickness of horizontal lines)
+END
diff --git a/src/VBox/Additions/common/crOpenGL/passthrough/passthroughspu_init.c b/src/VBox/Additions/common/crOpenGL/passthrough/passthroughspu_init.c
new file mode 100644
index 00000000..c08a17a4
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/passthrough/passthroughspu_init.c
@@ -0,0 +1,64 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "cr_error.h"
+#include "passthroughspu.h"
+
+static SPUFunctions passthrough_functions = {
+ NULL, /* CHILD COPY */
+ NULL, /* DATA */
+ _cr_passthrough_table /* THE ACTUAL FUNCTIONS */
+};
+
+static SPUFunctions *
+passthroughSPUInit( int id, SPU *child, SPU *self,
+ unsigned int context_id,
+ unsigned int num_contexts )
+{
+ (void) id;
+ (void) self;
+ (void) context_id;
+ (void) num_contexts;
+
+ if (child == NULL)
+ {
+ crError( "You can't load the passthrough SPU as the last SPU in a chain!" );
+ }
+ BuildPassthroughTable( child );
+ return &passthrough_functions;
+}
+
+static void
+passthroughSPUSelfDispatch(SPUDispatchTable *parent)
+{
+ (void)parent;
+}
+
+static int
+passthroughSPUCleanup(void)
+{
+ return 1;
+}
+
+static SPUOptions passthroughSPUOptions[] = {
+ { NULL, CR_BOOL, 0, NULL, NULL, NULL, NULL, NULL },
+};
+
+
+int SPULoad( char **name, char **super, SPUInitFuncPtr *init,
+ SPUSelfDispatchFuncPtr *self, SPUCleanupFuncPtr *cleanup,
+ SPUOptionsPtr *options, int *flags )
+{
+ *name = "passthrough";
+ *super = NULL;
+ *init = passthroughSPUInit;
+ *self = passthroughSPUSelfDispatch;
+ *cleanup = passthroughSPUCleanup;
+ *options = passthroughSPUOptions;
+ *flags = (SPU_NO_PACKER|SPU_NOT_TERMINAL|SPU_MAX_SERVERS_ZERO);
+
+ return 1;
+}
diff --git a/src/VBox/Additions/common/crOpenGL/stub.c b/src/VBox/Additions/common/crOpenGL/stub.c
new file mode 100644
index 00000000..f5369c6e
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/stub.c
@@ -0,0 +1,548 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "cr_spu.h"
+#include "cr_error.h"
+#include "cr_mem.h"
+#include "stub.h"
+#include <iprt/thread.h>
+
+#ifdef GLX
+Display* stubGetWindowDisplay(WindowInfo *pWindow)
+{
+#if defined(CR_NEWWINTRACK)
+ if ((NIL_RTTHREAD!=stub.hSyncThread) && (RTThreadNativeSelf()==RTThreadGetNative(stub.hSyncThread)))
+ {
+ if (pWindow && pWindow->dpy && !pWindow->syncDpy)
+ {
+ crDebug("going to XOpenDisplay(%s)", pWindow->dpyName);
+ pWindow->syncDpy = XOpenDisplay(pWindow->dpyName);
+ if (!pWindow->syncDpy)
+ {
+ crWarning("Failed to open display %s", pWindow->dpyName);
+ }
+ return pWindow->syncDpy;
+ }
+ else
+ {
+ return pWindow ? pWindow->syncDpy:NULL;
+ }
+ }
+ else
+#endif
+ {
+ return pWindow ? pWindow->dpy:NULL;
+ }
+}
+#endif
+
+/**
+ * Returns -1 on error
+ */
+GLint APIENTRY crCreateContext(char *dpyName, GLint visBits)
+{
+ ContextInfo *context;
+ stubInit();
+ /* XXX in Chromium 1.5 and earlier, the last parameter was UNDECIDED.
+ * That didn't seem right so it was changed to CHROMIUM. (Brian)
+ */
+ context = stubNewContext(dpyName, visBits, CHROMIUM, 0
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , NULL
+#endif
+ );
+ return context ? (int) context->id : -1;
+}
+
+void APIENTRY crDestroyContext( GLint context )
+{
+ stubDestroyContext(context);
+}
+
+void APIENTRY crMakeCurrent( GLint window, GLint context )
+{
+ WindowInfo *winInfo = (WindowInfo *)
+ crHashtableSearch(stub.windowTable, (unsigned int) window);
+ ContextInfo *contextInfo = (ContextInfo *)
+ crHashtableSearch(stub.contextTable, context);
+ if (contextInfo && contextInfo->type == NATIVE) {
+ crWarning("Can't call crMakeCurrent with native GL context");
+ return;
+ }
+
+ stubMakeCurrent(winInfo, contextInfo);
+}
+
+GLint APIENTRY crGetCurrentContext( void )
+{
+ ContextInfo *context;
+ stubInit();
+ context = stubGetCurrentContext();
+ if (context)
+ return (GLint) context->id;
+ else
+ return 0;
+}
+
+GLint APIENTRY crGetCurrentWindow( void )
+{
+ ContextInfo *context;
+ stubInit();
+ context = stubGetCurrentContext();
+ if (context && context->currentDrawable)
+ return context->currentDrawable->spuWindow;
+ else
+ return -1;
+}
+
+void APIENTRY crSwapBuffers( GLint window, GLint flags )
+{
+ WindowInfo *winInfo = (WindowInfo *)
+ crHashtableSearch(stub.windowTable, (unsigned int) window);
+ if (winInfo)
+ stubSwapBuffers(winInfo, flags);
+}
+
+/**
+ * Returns -1 on error
+ */
+GLint APIENTRY crWindowCreate( const char *dpyName, GLint visBits )
+{
+ stubInit();
+ return stubNewWindow( dpyName, visBits );
+}
+
+void APIENTRY crWindowDestroy( GLint window )
+{
+ stubDestroyWindow( 0, window );
+}
+
+void APIENTRY crWindowSize( GLint window, GLint w, GLint h )
+{
+ const WindowInfo *winInfo = (const WindowInfo *)
+ crHashtableSearch(stub.windowTable, (unsigned int) window);
+ if (winInfo && winInfo->type == CHROMIUM)
+ {
+ crDebug("Dispatched crWindowSize (%i)", window);
+ stub.spu->dispatch_table.WindowSize( window, w, h );
+ }
+}
+
+void APIENTRY crWindowPosition( GLint window, GLint x, GLint y )
+{
+ const WindowInfo *winInfo = (const WindowInfo *)
+ crHashtableSearch(stub.windowTable, (unsigned int) window);
+ if (winInfo && winInfo->type == CHROMIUM)
+ {
+ crDebug("Dispatched crWindowPosition (%i)", window);
+ stub.spu->dispatch_table.WindowPosition( window, x, y );
+ }
+}
+
+void APIENTRY crWindowVisibleRegion( GLint window, GLint cRects, const void *pRects )
+{
+ const WindowInfo *winInfo = (const WindowInfo *)
+ crHashtableSearch(stub.windowTable, (unsigned int) window);
+ if (winInfo && winInfo->type == CHROMIUM)
+ {
+ crDebug("Dispatched crWindowVisibleRegion (%i, cRects=%i)", window, cRects);
+ stub.spu->dispatch_table.WindowVisibleRegion( window, cRects, pRects );
+ }
+}
+
+void APIENTRY crVBoxTexPresent(GLuint texture, GLuint cfg, GLint xPos, GLint yPos, GLint cRects, const GLint *pRects)
+{
+ RT_NOREF(texture, cfg, xPos, yPos, cRects, pRects);
+ crError("not expected!");
+}
+
+void APIENTRY crWindowShow( GLint window, GLint flag )
+{
+ WindowInfo *winInfo = (WindowInfo *)
+ crHashtableSearch(stub.windowTable, (unsigned int) window);
+ if (winInfo && winInfo->type == CHROMIUM)
+ stub.spu->dispatch_table.WindowShow( window, flag );
+ winInfo->mapped = flag ? GL_TRUE : GL_FALSE;
+}
+
+void APIENTRY stub_GetChromiumParametervCR( GLenum target, GLuint index, GLenum type, GLsizei count, GLvoid *values )
+{
+ char **ret;
+ switch( target )
+ {
+ case GL_HEAD_SPU_NAME_CR:
+ ret = (char **) values;
+ *ret = stub.spu->name;
+ return;
+ default:
+ stub.spu->dispatch_table.GetChromiumParametervCR( target, index, type, count, values );
+ break;
+ }
+}
+
+/*
+ * Updates geometry info for given spu window.
+ * Returns GL_TRUE if it changed since last call, GL_FALSE otherwise.
+ * bForceUpdate - forces dispatching of geometry info even if it's unchanged
+ */
+GLboolean stubUpdateWindowGeometry(WindowInfo *pWindow, GLboolean bForceUpdate)
+{
+ int winX, winY;
+ unsigned int winW, winH;
+ GLboolean res = GL_FALSE;
+
+ CRASSERT(pWindow);
+
+ stubGetWindowGeometry(pWindow, &winX, &winY, &winW, &winH);
+
+ /** @todo remove "if (winW && winH)"?*/
+ if (winW && winH) {
+ if (stub.trackWindowSize) {
+ if (bForceUpdate || winW != pWindow->width || winH != pWindow->height) {
+ crDebug("Dispatched WindowSize (%i)", pWindow->spuWindow);
+#ifdef VBOX_WITH_WDDM
+ if (!stub.bRunningUnderWDDM || pWindow->mapped)
+#endif
+ {
+ stub.spuDispatch.WindowSize(pWindow->spuWindow, winW, winH);
+ }
+ pWindow->width = winW;
+ pWindow->height = winH;
+ res = GL_TRUE;
+ }
+ }
+ if (stub.trackWindowPos) {
+ if (bForceUpdate || winX != pWindow->x || winY != pWindow->y) {
+ crDebug("Dispatched WindowPosition (%i)", pWindow->spuWindow);
+#ifdef VBOX_WITH_WDDM
+ if (!stub.bRunningUnderWDDM || pWindow->mapped)
+#endif
+ {
+ stub.spuDispatch.WindowPosition(pWindow->spuWindow, winX, winY);
+ }
+ pWindow->x = winX;
+ pWindow->y = winY;
+ res = GL_TRUE;
+ }
+ }
+ }
+
+ return res;
+}
+
+#ifdef WINDOWS
+/*
+ * Updates visible regions for given spu window.
+ * Returns GL_TRUE if regions changed since last call, GL_FALSE otherwise.
+ */
+GLboolean stubUpdateWindowVisibileRegions(WindowInfo *pWindow)
+{
+ HRGN hVisRgn;
+ HWND hwnd;
+ DWORD dwCount;
+ LPRGNDATA lpRgnData;
+ POINT pt;
+ int iret;
+
+ if (!pWindow) return GL_FALSE;
+ hwnd = pWindow->hWnd;
+ if (!hwnd) return GL_FALSE;
+
+ if (hwnd!=WindowFromDC(pWindow->drawable))
+ {
+ crWarning("Window(%i) DC is no longer valid", pWindow->spuWindow);
+ return GL_FALSE;
+ }
+
+ hVisRgn = CreateRectRgn(0,0,0,0);
+ iret = GetRandomRgn(pWindow->drawable, hVisRgn, SYSRGN);
+
+ if (iret==1)
+ {
+ /** @todo check win95/win98 here, as rects should be already in client space there*/
+ /* Convert screen related rectangles to client related rectangles */
+ pt.x = 0;
+ pt.y = 0;
+ ScreenToClient(hwnd, &pt);
+ OffsetRgn(hVisRgn, pt.x, pt.y);
+
+ /*
+ dwCount = GetRegionData(hVisRgn, 0, NULL);
+ lpRgnData = crAlloc(dwCount);
+ crDebug("GetRandomRgn returned 1, dwCount=%d", dwCount);
+ GetRegionData(hVisRgn, dwCount, lpRgnData);
+ crDebug("Region consists of %d rects", lpRgnData->rdh.nCount);
+
+ pRects = (RECT*) lpRgnData->Buffer;
+ for (i=0; i<lpRgnData->rdh.nCount; ++i)
+ {
+ crDebug("Rgn[%d] = (%d, %d, %d, %d)", i, pRects[i].left, pRects[i].top, pRects[i].right, pRects[i].bottom);
+ }
+ crFree(lpRgnData);
+ */
+
+ if (pWindow->hVisibleRegion==INVALID_HANDLE_VALUE
+ || !EqualRgn(pWindow->hVisibleRegion, hVisRgn))
+ {
+ DeleteObject(pWindow->hVisibleRegion);
+ pWindow->hVisibleRegion = hVisRgn;
+
+ dwCount = GetRegionData(hVisRgn, 0, NULL);
+ lpRgnData = crAlloc(dwCount);
+
+ if (lpRgnData)
+ {
+ GetRegionData(hVisRgn, dwCount, lpRgnData);
+ crDebug("Dispatched WindowVisibleRegion (%i, cRects=%i)", pWindow->spuWindow, lpRgnData->rdh.nCount);
+ stub.spuDispatch.WindowVisibleRegion(pWindow->spuWindow, lpRgnData->rdh.nCount, (GLint*) lpRgnData->Buffer);
+ crFree(lpRgnData);
+ return GL_TRUE;
+ }
+ else crWarning("GetRegionData failed, VisibleRegions update failed");
+ }
+ else
+ {
+ DeleteObject(hVisRgn);
+ }
+ }
+ else
+ {
+ crWarning("GetRandomRgn returned (%d) instead of (1), VisibleRegions update failed", iret);
+ DeleteObject(hVisRgn);
+ }
+
+ return GL_FALSE;
+}
+
+# ifndef CR_NEWWINTRACK
+static void stubCBCheckWindowsInfo(unsigned long key, void *data1, void *data2)
+{
+ WindowInfo *winInfo = (WindowInfo *) data1;
+ CWPRETSTRUCT *pMsgInfo = (PCWPRETSTRUCT) data2;
+
+ (void) key;
+
+ if (winInfo && pMsgInfo && winInfo->type == CHROMIUM)
+ {
+ switch (pMsgInfo->message)
+ {
+ case WM_MOVING:
+ case WM_SIZING:
+ case WM_MOVE:
+ case WM_CREATE:
+ case WM_SIZE:
+ {
+ GLboolean changed = stub.trackWindowVisibleRgn && stubUpdateWindowVisibileRegions(winInfo);
+
+ if (stubUpdateWindowGeometry(winInfo, GL_FALSE) || changed)
+ {
+ stubForcedFlush(0);
+ }
+ break;
+ }
+
+ case WM_SHOWWINDOW:
+ case WM_ACTIVATEAPP:
+ case WM_PAINT:
+ case WM_NCPAINT:
+ case WM_NCACTIVATE:
+ case WM_ERASEBKGND:
+ {
+ if (stub.trackWindowVisibleRgn && stubUpdateWindowVisibileRegions(winInfo))
+ {
+ stubForcedFlush(0);
+ }
+ break;
+ }
+
+ default:
+ {
+ if (stub.trackWindowVisibleRgn && stubUpdateWindowVisibileRegions(winInfo))
+ {
+ crDebug("Visibility info updated due to unknown hooked message (%d)", pMsgInfo->message);
+ stubForcedFlush(0);
+ }
+ break;
+ }
+ }
+ }
+}
+
+LRESULT CALLBACK stubCBWindowMessageHookProc(int nCode, WPARAM wParam, LPARAM lParam)
+{
+ CWPRETSTRUCT *pMsgInfo = (PCWPRETSTRUCT) lParam;
+
+ if (nCode>=0 && pMsgInfo)
+ {
+ switch (pMsgInfo->message)
+ {
+ case WM_MOVING:
+ case WM_SIZING:
+ case WM_MOVE:
+ case WM_ACTIVATEAPP:
+ case WM_NCPAINT:
+ case WM_NCACTIVATE:
+ case WM_ERASEBKGND:
+ case WM_CREATE:
+ case WM_SIZE:
+ case WM_SHOWWINDOW:
+ {
+ crHashtableWalk(stub.windowTable, stubCBCheckWindowsInfo, (void *) lParam);
+ break;
+ }
+
+ /** @todo remove it*/
+ default:
+ {
+ /*crDebug("hook: unknown message (%d)", pMsgInfo->message);*/
+ crHashtableWalk(stub.windowTable, stubCBCheckWindowsInfo, (void *) lParam);
+ break;
+ }
+ }
+ }
+
+ return CallNextHookEx(stub.hMessageHook, nCode, wParam, lParam);
+}
+
+void stubInstallWindowMessageHook()
+{
+ stub.hMessageHook = SetWindowsHookEx(WH_CALLWNDPROCRET, stubCBWindowMessageHookProc, 0, crThreadID());
+
+ if (!stub.hMessageHook)
+ crWarning("Window message hook install failed! (not fatal)");
+}
+
+void stubUninstallWindowMessageHook()
+{
+ if (stub.hMessageHook)
+ UnhookWindowsHookEx(stub.hMessageHook);
+}
+# endif /*# ifndef CR_NEWWINTRACK*/
+
+#elif defined(GLX) //#ifdef WINDOWS
+void stubCheckXExtensions(WindowInfo *pWindow)
+{
+ int evb, erb, vmi=0, vma=0;
+ Display *dpy = stubGetWindowDisplay(pWindow);
+
+ stub.bXExtensionsChecked = GL_TRUE;
+ stub.trackWindowVisibleRgn = 0;
+
+ XLOCK(dpy);
+ if (XCompositeQueryExtension(dpy, &evb, &erb)
+ && XCompositeQueryVersion(dpy, &vma, &vmi)
+ && (vma>0 || vmi>=4))
+ {
+ stub.bHaveXComposite = GL_TRUE;
+ crDebug("XComposite %i.%i", vma, vmi);
+ vma=0;
+ vmi=0;
+ if (XFixesQueryExtension(dpy, &evb, &erb)
+ && XFixesQueryVersion(dpy, &vma, &vmi)
+ && vma>=2)
+ {
+ crDebug("XFixes %i.%i", vma, vmi);
+ stub.bHaveXFixes = GL_TRUE;
+ stub.trackWindowVisibleRgn = 1;
+ XUNLOCK(dpy);
+ return;
+ }
+ else
+ {
+ crWarning("XFixes not found or old version (%i.%i), no VisibilityTracking", vma, vmi);
+ }
+ }
+ else
+ {
+ crWarning("XComposite not found or old version (%i.%i), no VisibilityTracking", vma, vmi);
+ }
+ XUNLOCK(dpy);
+ return;
+}
+
+/*
+ * Updates visible regions for given spu window.
+ * Returns GL_TRUE if regions changed since last call, GL_FALSE otherwise.
+ */
+GLboolean stubUpdateWindowVisibileRegions(WindowInfo *pWindow)
+{
+ XserverRegion xreg;
+ int cRects, i;
+ XRectangle *pXRects;
+ GLint* pGLRects;
+ Display *dpy;
+ bool bNoUpdate = false;
+
+ if (!stub.bXExtensionsChecked)
+ {
+ stubCheckXExtensions(pWindow);
+ if (!stub.trackWindowVisibleRgn)
+ {
+ return GL_FALSE;
+ }
+ }
+
+ dpy = stubGetWindowDisplay(pWindow);
+
+ /** @todo see comment regarding size/position updates and XSync, same applies to those functions but
+ * it seems there's no way to get even based updates for this. Or I've failed to find the appropriate extension.
+ */
+ XLOCK(dpy);
+ xreg = XCompositeCreateRegionFromBorderClip(dpy, pWindow->drawable);
+ pXRects = XFixesFetchRegion(dpy, xreg, &cRects);
+ XFixesDestroyRegion(dpy, xreg);
+ XUNLOCK(dpy);
+
+ /* Check for compiz main window */
+ if (!pWindow->pVisibleRegions && !cRects)
+ {
+ bNoUpdate = true;
+ }
+
+ if (!bNoUpdate
+ && (!pWindow->pVisibleRegions
+ || pWindow->cVisibleRegions!=cRects
+ || (pWindow->pVisibleRegions && crMemcmp(pWindow->pVisibleRegions, pXRects, cRects * sizeof(XRectangle)))))
+ {
+ if (pWindow->pVisibleRegions)
+ {
+ XFree(pWindow->pVisibleRegions);
+ }
+
+ pWindow->pVisibleRegions = pXRects;
+ pWindow->cVisibleRegions = cRects;
+
+ pGLRects = crAlloc(cRects ? 4*cRects*sizeof(GLint) : 4*sizeof(GLint));
+ if (!pGLRects)
+ {
+ crWarning("stubUpdateWindowVisibileRegions: failed to allocate %lu bytes",
+ (unsigned long)(4*cRects*sizeof(GLint)));
+ return GL_FALSE;
+ }
+
+ //crDebug("Got %i rects.", cRects);
+ for (i=0; i<cRects; ++i)
+ {
+ pGLRects[4*i+0] = pXRects[i].x;
+ pGLRects[4*i+1] = pXRects[i].y;
+ pGLRects[4*i+2] = pXRects[i].x+pXRects[i].width;
+ pGLRects[4*i+3] = pXRects[i].y+pXRects[i].height;
+ //crDebug("Rect[%i]=(%i,%i,%i,%i)", i, pGLRects[4*i+0], pGLRects[4*i+1], pGLRects[4*i+2], pGLRects[4*i+3]);
+ }
+
+ crDebug("Dispatched WindowVisibleRegion (%i, cRects=%i)", pWindow->spuWindow, cRects);
+ stub.spuDispatch.WindowVisibleRegion(pWindow->spuWindow, cRects, pGLRects);
+ crFree(pGLRects);
+ return GL_TRUE;
+ }
+ else
+ {
+ XFree(pXRects);
+ }
+
+ return GL_FALSE;
+}
+#endif //#ifdef WINDOWS
diff --git a/src/VBox/Additions/common/crOpenGL/stub.h b/src/VBox/Additions/common/crOpenGL/stub.h
new file mode 100644
index 00000000..1dd5faa2
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/stub.h
@@ -0,0 +1,370 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+
+/*
+ * How this all works...
+ *
+ * This directory implements three different interfaces to Chromium:
+ *
+ * 1. the Chromium interface - this is defined by the functions that start
+ * with the "cr" prefix and are defined in chromium.h and implemented in
+ * stub.c. Typically, this is used by parallel apps (like psubmit).
+ *
+ * 2. GLX emulation interface - the glX*() functions are emulated here.
+ * When glXCreateContext() is called we may either create a real, native
+ * GLX context or a Chromium context (depending on match_window_title and
+ * minimum_window_size).
+ *
+ * 3. WGL emulation interface - the wgl*() functions are emulated here.
+ * When wglCreateContext() is called we may either create a real, native
+ * WGL context or a Chromium context (depending on match_window_title and
+ * minimum_window_size).
+ *
+ *
+ */
+
+#ifndef GA_INCLUDED_SRC_common_crOpenGL_stub_h
+#define GA_INCLUDED_SRC_common_crOpenGL_stub_h
+#ifndef RT_WITHOUT_PRAGMA_ONCE
+# pragma once
+#endif
+
+#include "chromium.h"
+#include "cr_version.h"
+#include "cr_hash.h"
+#include "cr_process.h"
+#include "cr_spu.h"
+#include "cr_threads.h"
+#include "spu_dispatch_table.h"
+
+#ifdef GLX
+#include <X11/extensions/XShm.h>
+#include <sys/shm.h>
+#include <X11/extensions/Xdamage.h>
+#include <X11/extensions/Xcomposite.h>
+#include <X11/extensions/Xfixes.h>
+#endif
+
+#if defined(WINDOWS) || defined(Linux) || defined(SunOS)
+# define CR_NEWWINTRACK
+#endif
+
+#if !defined(CHROMIUM_THREADSAFE) && defined(CR_NEWWINTRACK)
+# error CHROMIUM_THREADSAFE have to be defined
+#endif
+
+#ifdef CHROMIUM_THREADSAFE
+# include <cr_threads.h>
+#endif
+
+#if 0 && defined(CR_NEWWINTRACK) && !defined(WINDOWS)
+#define XLOCK(dpy) XLockDisplay(dpy)
+#define XUNLOCK(dpy) XUnlockDisplay(dpy)
+#else
+#define XLOCK(dpy)
+#define XUNLOCK(dpy)
+#endif
+
+/* When we first create a rendering context we can't be sure whether
+ * it'll be handled by Chromium or as a native GLX/WGL context. So in
+ * CreateContext() we'll mark the ContextInfo object as UNDECIDED then
+ * switch it to either NATIVE or CHROMIUM the first time MakeCurrent()
+ * is called. In MakeCurrent() we can use a criteria like window size
+ * or window title to decide between CHROMIUM and NATIVE.
+ */
+typedef enum
+{
+ UNDECIDED,
+ CHROMIUM,
+ NATIVE
+} ContextType;
+
+#define MAX_DPY_NAME 1000
+
+typedef struct context_info_t ContextInfo;
+typedef struct window_info_t WindowInfo;
+
+#ifdef GLX
+typedef struct glxpixmap_info_t GLX_Pixmap_t;
+
+struct glxpixmap_info_t
+{
+ int x, y;
+ unsigned int w, h, border, depth;
+ GLenum format;
+ Window root;
+ GLenum target;
+ GC gc;
+ Pixmap hShmPixmap; /* Shared memory pixmap object, if it's supported*/
+ Damage hDamage; /* damage xserver handle*/
+ Bool bPixmapImageDirty;
+ Region pDamageRegion;
+};
+#endif
+
+struct context_info_t
+{
+ char dpyName[MAX_DPY_NAME];
+ GLint spuContext; /* returned by head SPU's CreateContext() */
+ ContextType type; /* CHROMIUM, NATIVE or UNDECIDED */
+ unsigned long id; /* the client-visible handle */
+ GLint visBits;
+ WindowInfo *currentDrawable;
+
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ GLint spuConnection;
+ struct VBOXUHGSMI *pHgsmi;
+#endif
+
+#ifdef CHROMIUM_THREADSAFE
+ VBOXTLSREFDATA
+#endif
+
+#ifdef WINDOWS
+ HGLRC hglrc;
+#elif defined(DARWIN)
+ ContextInfo *share;
+ CGLContextObj cglc;
+
+ /* CGLContextEnable (CGLEnable, CGLDisable, and CGLIsEnabled) */
+ unsigned int options;
+
+ /* CGLContextParameter (CGLSetParameter and CGLGetParameter) */
+ GLint parambits;
+ long swap_rect[4], swap_interval;
+ unsigned long client_storage;
+ long surf_order, surf_opacy;
+
+ long disp_mask;
+#elif defined(GLX)
+ Display *dpy;
+ ContextInfo *share;
+ Bool direct;
+ GLXContext glxContext;
+ CRHashTable *pGLXPixmapsHash;
+ Bool damageQueryFailed;
+ int damageEventsBase;
+#endif
+};
+
+#ifdef DARWIN
+enum {
+ VISBIT_SWAP_RECT,
+ VISBIT_SWAP_INTERVAL,
+ VISBIT_CLIENT_STORAGE
+};
+#endif
+
+struct window_info_t
+{
+ char dpyName[MAX_DPY_NAME];
+ int x, y;
+ unsigned int width, height;
+ ContextType type;
+ GLint spuWindow; /* returned by head SPU's WindowCreate() */
+ ContextInfo *pOwner; /* ctx which created this window */
+ GLboolean mapped;
+#ifdef WINDOWS
+ HDC drawable;
+ HRGN hVisibleRegion;
+ DWORD dmPelsWidth;
+ DWORD dmPelsHeight;
+ HWND hWnd;
+#elif defined(DARWIN)
+ CGSConnectionID connection;
+ CGSWindowID drawable;
+ CGSSurfaceID surface;
+#elif defined(GLX)
+ Display *dpy;
+# ifdef CR_NEWWINTRACK
+ Display *syncDpy;
+# endif
+ GLXDrawable drawable;
+ XRectangle *pVisibleRegions;
+ GLint cVisibleRegions;
+#endif
+#ifdef CR_NEWWINTRACK
+ uint32_t u32ClientID;
+#endif
+};
+
+/* "Global" variables for the stub library */
+typedef struct {
+ /* the first SPU in the SPU chain on this app node */
+ SPU *spu;
+
+ /* OpenGL/SPU dispatch tables */
+ crOpenGLInterface wsInterface;
+ SPUDispatchTable spuDispatch;
+ SPUDispatchTable nativeDispatch;
+ GLboolean haveNativeOpenGL;
+
+ /* config options */
+ int appDrawCursor;
+ GLuint minChromiumWindowWidth;
+ GLuint minChromiumWindowHeight;
+ GLuint maxChromiumWindowWidth;
+ GLuint maxChromiumWindowHeight;
+ GLuint matchChromiumWindowCount;
+ GLuint matchChromiumWindowCounter;
+ GLuint *matchChromiumWindowID;
+ GLuint numIgnoreWindowID;
+ char *matchWindowTitle;
+ int ignoreFreeglutMenus;
+ int trackWindowSize;
+ int trackWindowPos;
+ int trackWindowVisibility;
+ int trackWindowVisibleRgn;
+ char *spu_dir;
+ int force_pbuffers;
+
+ /* thread safety stuff */
+ GLboolean threadSafe;
+#ifdef CHROMIUM_THREADSAFE
+ CRtsd dispatchTSD;
+ CRmutex mutex;
+#endif
+
+ CRpid mothershipPID;
+
+ /* contexts */
+ int freeContextNumber;
+ CRHashTable *contextTable;
+#ifndef CHROMIUM_THREADSAFE
+ ContextInfo *currentContext; /* may be NULL */
+#endif
+
+ /* windows */
+ CRHashTable *windowTable;
+
+#ifdef GLX
+ /* Shared memory, used to transfer XServer pixmaps data into client memory */
+ XShmSegmentInfo xshmSI;
+ GLboolean bShmInitFailed;
+
+ CRHashTable *pGLXPixmapsHash;
+
+ GLboolean bXExtensionsChecked;
+ GLboolean bHaveXComposite;
+ GLboolean bHaveXFixes;
+#endif
+
+#ifdef WINDOWS
+# ifndef CR_NEWWINTRACK
+ HHOOK hMessageHook;
+# endif
+# ifdef VBOX_WITH_WDDM
+ bool bRunningUnderWDDM;
+# endif
+#endif
+
+#ifdef CR_NEWWINTRACK
+ RTTHREAD hSyncThread;
+ bool volatile bShutdownSyncThread;
+#endif
+
+} Stub;
+
+#ifdef CHROMIUM_THREADSAFE
+/* we place the g_stubCurrentContextTLS outside the Stub data because Stub data is inited by the client's call,
+ * while we need g_stubCurrentContextTLS the g_stubCurrentContextTLS to be valid at any time to be able to handle
+ * THREAD_DETACH cleanup on windows.
+ * Note that we can not do
+ * STUB_INIT_LOCK();
+ * if (stub_initialized) stubSetCurrentContext(NULL);
+ * STUB_INIT_UNLOCK();
+ * on THREAD_DETACH since it may cause deadlock, i.e. in this situation loader lock is acquired first and then the init lock,
+ * but since we use GetModuleFileName in crGetProcName called from stubInitLocked, the lock order might be the oposite.
+ * Note that GetModuleFileName acquires the loader lock.
+ * */
+extern CRtsd g_stubCurrentContextTSD;
+
+DECLINLINE(ContextInfo*) stubGetCurrentContext(void)
+{
+ ContextInfo* ctx;
+ VBoxTlsRefGetCurrentFunctional(ctx, ContextInfo, &g_stubCurrentContextTSD);
+ return ctx;
+}
+# define stubSetCurrentContext(_ctx) VBoxTlsRefSetCurrent(ContextInfo, &g_stubCurrentContextTSD, _ctx)
+#else
+# define stubGetCurrentContext() (stub.currentContext)
+# define stubSetCurrentContext(_ctx) do { stub.currentContext = (_ctx); } while (0)
+#endif
+
+extern Stub stub;
+
+extern DECLEXPORT(SPUDispatchTable) glim;
+extern SPUDispatchTable stubThreadsafeDispatch;
+extern DECLEXPORT(SPUDispatchTable) stubNULLDispatch;
+
+#if defined(GLX) || defined (WINDOWS)
+extern GLboolean stubUpdateWindowVisibileRegions(WindowInfo *pWindow);
+#endif
+
+#ifdef WINDOWS
+
+/* WGL versions */
+extern WindowInfo *stubGetWindowInfo( HDC drawable );
+
+extern void stubInstallWindowMessageHook();
+extern void stubUninstallWindowMessageHook();
+
+#elif defined(DARWIN)
+
+extern CGSConnectionID _CGSDefaultConnection(void);
+extern OSStatus CGSGetWindowLevel( CGSConnectionID cid, CGSWindowID wid, CGWindowLevel *level );
+extern OSStatus CGSSetWindowAlpha( const CGSConnectionID cid, CGSWindowID wid, float alpha );
+
+/* These don't seem to be included in the OSX glext.h ... */
+extern void glPointParameteri( GLenum pname, GLint param );
+extern void glPointParameteriv( GLenum pname, const GLint * param );
+
+extern WindowInfo *stubGetWindowInfo( CGSWindowID drawable );
+
+#elif defined(GLX)
+
+/* GLX versions */
+extern WindowInfo *stubGetWindowInfo( Display *dpy, GLXDrawable drawable );
+extern void stubUseXFont( Display *dpy, Font font, int first, int count, int listbase );
+extern Display* stubGetWindowDisplay(WindowInfo *pWindow);
+
+extern void stubCheckXExtensions(WindowInfo *pWindow);
+#endif
+
+
+extern ContextInfo *stubNewContext(char *dpyName, GLint visBits, ContextType type, unsigned long shareCtx
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , struct VBOXUHGSMI *pHgsmi
+#endif
+ );
+extern void stubConChromiumParameteriCR(GLint con, GLenum param, GLint value);
+extern void stubConChromiumParametervCR(GLint con, GLenum target, GLenum type, GLsizei count, const GLvoid *values);
+extern GLboolean stubCtxCreate(ContextInfo *context);
+extern GLboolean stubCtxCheckCreate(ContextInfo *context);
+extern void stubDestroyContext( unsigned long contextId );
+extern GLboolean stubMakeCurrent( WindowInfo *window, ContextInfo *context );
+extern GLint stubNewWindow( const char *dpyName, GLint visBits );
+extern void stubDestroyWindow( GLint con, GLint window );
+extern void stubSwapBuffers(WindowInfo *window, GLint flags);
+extern void stubGetWindowGeometry(WindowInfo *win, int *x, int *y, unsigned int *w, unsigned int *h);
+extern GLboolean stubUpdateWindowGeometry(WindowInfo *pWindow, GLboolean bForceUpdate);
+extern GLboolean stubIsWindowVisible(WindowInfo *win);
+extern bool stubInit(void);
+
+extern void stubForcedFlush(GLint con);
+extern void stubConFlush(GLint con);
+extern void APIENTRY stub_GetChromiumParametervCR( GLenum target, GLuint index, GLenum type, GLsizei count, GLvoid *values );
+
+extern void APIENTRY glBoundsInfoCR(const CRrecti *, const GLbyte *, GLint, GLint);
+
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+# define CR_CTX_CON(_pCtx) ((_pCtx)->spuConnection)
+#else
+# define CR_CTX_CON(_pCtx) (0)
+#endif
+
+#endif /* !GA_INCLUDED_SRC_common_crOpenGL_stub_h */
diff --git a/src/VBox/Additions/common/crOpenGL/stub_common.py b/src/VBox/Additions/common/crOpenGL/stub_common.py
new file mode 100755
index 00000000..05127343
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/stub_common.py
@@ -0,0 +1,282 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+from __future__ import print_function
+import sys
+curver = sys.version_info[0] + sys.version_info[1]/10.0
+if curver < 2.2:
+ print("Your python is version %g. Chromium requires at least"%(curver), file=sys.stderr)
+ print("version 2.2. Please upgrade your python installation.", file=sys.stderr)
+ sys.exit(1)
+
+import string;
+import re;
+
+def CopyrightC( ):
+ print("""/* Copyright (c) 2001, Stanford University
+ All rights reserved.
+
+ See the file LICENSE.txt for information on redistributing this software. */
+ """)
+
+def CopyrightDef( ):
+ print("""; Copyright (c) 2001, Stanford University
+ ; All rights reserved.
+ ;
+ ; See the file LICENSE.txt for information on redistributing this software.
+ """)
+
+def DecoderName( glName ):
+ return "crUnpack" + glName
+
+def OpcodeName( glName ):
+ # This is a bit of a hack. We want to implement the glVertexAttrib*NV
+ # functions in terms of the glVertexAttrib*ARB opcodes.
+ m = re.search( "VertexAttrib([1234](ub|b|us|s|ui|i|f|d|)v?)NV", glName )
+ if m:
+ dataType = m.group(1)
+ if dataType == "4ub":
+ dataType = "4Nub"
+ elif dataType == "4ubv":
+ dataType = "4Nubv"
+ glName = "VertexAttrib" + dataType + "ARB"
+ return "CR_" + string.upper( glName ) + "_OPCODE"
+
+def ExtendedOpcodeName( glName ):
+ return "CR_" + string.upper( glName ) + "_EXTEND_OPCODE"
+
+def PackFunction( glName ):
+ return "crPack" + glName
+
+def DoPackFunctionMapping( glName ):
+ return "__glpack_" + glName
+
+def DoStateFunctionMapping( glName ):
+ return "__glstate_" + glName
+
+def DoImmediateMapping( glName ):
+ return "__glim_" + glName
+
+
+
+# Annotations are a generalization of Specials (below).
+# Each line of an annotation file is a set of words.
+# The first word is a key; the remainder are all annotations
+# for that key. This is a useful model for grouping keys
+# (like GL function names) into overlapping subsets, all in
+# a single file.
+annotations = {}
+def LoadAnnotations(filename):
+ table = {}
+ try:
+ f = open(filename, "r")
+ except:
+ annotations[filename] = {}
+ return {}
+
+ for line in f.readlines():
+ line = line.strip()
+ if line == "" or line[0] == '#':
+ continue
+ subtable = {}
+ words = line.split()
+ for word in words[1:]:
+ subtable[word] = 1
+ table[words[0]] = subtable
+
+ annotations[filename] = table
+ return table
+
+def GetAnnotations( filename, key ):
+ table = {}
+ try:
+ table = annotations[filename]
+ except KeyError:
+ table = LoadAnnotations(filename)
+
+ try:
+ subtable = table[key]
+ except KeyError:
+ return []
+
+ return sorted(subtable.keys())
+
+def FindAnnotation( filename, key, subkey ):
+ table = {}
+ try:
+ table = annotations[filename]
+ except KeyError:
+ table = LoadAnnotations(filename)
+
+ try:
+ subtable = table[key]
+ except KeyError:
+ return 0
+
+ try:
+ return subtable[subkey]
+ except KeyError:
+ return 0
+
+
+
+specials = {}
+
+def LoadSpecials( filename ):
+ table = {}
+ try:
+ f = open( filename, "r" )
+ except:
+ specials[filename] = {}
+ return {}
+
+ for line in f.readlines():
+ line = string.strip(line)
+ if line == "" or line[0] == '#':
+ continue
+ table[line] = 1
+
+ specials[filename] = table
+ return table
+
+def FindSpecial( table_file, glName ):
+ table = {}
+ filename = table_file + "_special"
+ try:
+ table = specials[filename]
+ except KeyError:
+ table = LoadSpecials( filename )
+
+ try:
+ if (table[glName] == 1):
+ return 1
+ else:
+ return 0 #should never happen
+ except KeyError:
+ return 0
+
+def AllSpecials( table_file ):
+ table = {}
+ filename = table_file + "_special"
+ try:
+ table = specials[filename]
+ except KeyError:
+ table = LoadSpecials( filename )
+
+ return sorted(table.keys())
+
+def AllSpecials( table_file ):
+ filename = table_file + "_special"
+
+ table = {}
+ try:
+ table = specials[filename]
+ except KeyError:
+ table = LoadSpecials(filename)
+
+ return sorted(table.keys())
+
+def NumSpecials( table_file ):
+ filename = table_file + "_special"
+
+ table = {}
+ try:
+ table = specials[filename]
+ except KeyError:
+ table = LoadSpecials(filename)
+
+ return len(table.keys())
+
+lengths = {}
+lengths['GLbyte'] = 1
+lengths['GLubyte'] = 1
+lengths['GLshort'] = 2
+lengths['GLushort'] = 2
+lengths['GLint'] = 4
+lengths['GLuint'] = 4
+lengths['GLfloat'] = 4
+lengths['GLclampf'] = 4
+lengths['GLdouble'] = 8
+lengths['GLclampd'] = 8
+
+lengths['GLenum'] = 4
+lengths['GLboolean'] = 1
+lengths['GLsizei'] = 4
+lengths['GLbitfield'] = 4
+
+lengths['void'] = 0
+lengths['int'] = 4
+
+align_types = 1
+
+def FixAlignment( pos, alignment ):
+ # if we want double-alignment take word-alignment instead,
+ # yes, this is super-lame, but we know what we are doing
+ if alignment > 4:
+ alignment = 4
+ if align_types and alignment and ( pos % alignment ):
+ pos += alignment - ( pos % alignment )
+ return pos
+
+def WordAlign( pos ):
+ return FixAlignment( pos, 4 )
+
+def PointerSize():
+ return 8 # Leave room for a 64 bit pointer
+
+def PacketLength( arg_types ):
+ len = 0
+ for arg in arg_types:
+ if string.find( arg, '*') != -1:
+ size = PointerSize()
+ else:
+ temp_arg = re.sub("const ", "", arg)
+ size = lengths[temp_arg]
+ len = FixAlignment( len, size ) + size
+ len = WordAlign( len )
+ return len
+
+def InternalArgumentString( arg_names, arg_types ):
+ """Return string of C-style function declaration arguments."""
+ output = ''
+ for index in range(0,len(arg_names)):
+ if len(arg_names) != 1 and arg_names[index] == '':
+ continue
+ output += arg_types[index]
+ if arg_types[index][-1:] != '*' and arg_names[index] != '':
+ output += " ";
+ output += arg_names[index]
+ if index != len(arg_names) - 1:
+ output += ", "
+ return output
+
+def ArgumentString( arg_names, arg_types ):
+ """Return InternalArgumentString inside parenthesis."""
+ output = '( ' + InternalArgumentString(arg_names, arg_types) + ' )'
+ return output
+
+def InternalCallString( arg_names ):
+ output = ''
+ for index in range(0,len(arg_names)):
+ output += arg_names[index]
+ if arg_names[index] != '' and index != len(arg_names) - 1:
+ output += ", "
+ return output
+
+def CallString( arg_names ):
+ output = '( '
+ output += InternalCallString(arg_names)
+ output += " )"
+ return output
+
+def IsVector ( func_name ) :
+ m = re.search( r"^(SecondaryColor|Color|EdgeFlag|EvalCoord|Index|Normal|TexCoord|MultiTexCoord|Vertex|RasterPos|VertexAttrib|FogCoord|WindowPos|ProgramParameter)([1234]?)N?(ub|b|us|s|ui|i|f|d|)v(ARB|EXT|NV)?$", func_name )
+ if m :
+ if m.group(2) :
+ return string.atoi( m.group(2) )
+ else:
+ return 1
+ else:
+ return 0
diff --git a/src/VBox/Additions/common/crOpenGL/tsfuncs.py b/src/VBox/Additions/common/crOpenGL/tsfuncs.py
new file mode 100755
index 00000000..020b5cc7
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/tsfuncs.py
@@ -0,0 +1,47 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+
+apiutil.CopyrightC()
+
+print("""
+/* DO NOT EDIT - THIS FILE GENERATED BY THE tsfuncs.py SCRIPT */
+
+#include "stub.h"
+""")
+
+keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+for func_name in keys:
+ return_type = apiutil.ReturnType(func_name)
+ params = apiutil.Parameters(func_name)
+
+ print("static %s SPULOAD_APIENTRY ts_%s(%s)" % (return_type, func_name, apiutil.MakeDeclarationString(params) ))
+ print("{")
+ print("\tSPUDispatchTable *tab = (SPUDispatchTable *) crGetTSD(&stub.dispatchTSD);")
+
+ if return_type != "void":
+ print("\treturn ", end=" ")
+
+ print("\ttab->%s(%s);" % (func_name, apiutil.MakeCallString(params)))
+ print("}")
+ print("")
+
+
+print("SPUDispatchTable stubThreadsafeDispatch = {")
+
+for func_name in keys:
+ print("\tts_%s," % func_name)
+
+print("\tNULL, /* copyList */")
+print("\tNULL, /* copy_of */")
+print("\t0, /* mark */")
+print("\tNULL /* server */")
+print("};")
diff --git a/src/VBox/Additions/common/crOpenGL/utils.c b/src/VBox/Additions/common/crOpenGL/utils.c
new file mode 100644
index 00000000..a220d09d
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/utils.c
@@ -0,0 +1,876 @@
+/*
+ * (C) Copyright IBM Corporation 2002, 2004
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file utils.c
+ * Utility functions for DRI drivers.
+ *
+ * \author Ian Romanick <idr@us.ibm.com>
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include "mtypes.h"
+#include "extensions.h"
+#include "utils.h"
+#include "dispatch.h"
+
+int driDispatchRemapTable[ driDispatchRemapTable_size ];
+
+#if defined(USE_X86_ASM)
+#include "x86/common_x86_asm.h"
+#endif
+
+#if defined(USE_PPC_ASM)
+#include "ppc/common_ppc_features.h"
+#endif
+
+unsigned
+driParseDebugString( const char * debug,
+ const struct dri_debug_control * control )
+{
+ unsigned flag;
+
+
+ flag = 0;
+ if ( debug != NULL ) {
+ while( control->string != NULL ) {
+ if ( !strcmp( debug, "all" ) ||
+ strstr( debug, control->string ) != NULL ) {
+ flag |= control->flag;
+ }
+
+ control++;
+ }
+ }
+
+ return flag;
+}
+
+
+
+/**
+ * Create the \c GL_RENDERER string for DRI drivers.
+ *
+ * Almost all DRI drivers use a \c GL_RENDERER string of the form:
+ *
+ * "Mesa DRI <chip> <driver date> <AGP speed) <CPU information>"
+ *
+ * Using the supplied chip name, driver data, and AGP speed, this function
+ * creates the string.
+ *
+ * \param buffer Buffer to hold the \c GL_RENDERER string.
+ * \param hardware_name Name of the hardware.
+ * \param driver_date Driver date.
+ * \param agp_mode AGP mode (speed).
+ *
+ * \returns
+ * The length of the string stored in \c buffer. This does \b not include
+ * the terminating \c NUL character.
+ */
+unsigned
+driGetRendererString( char * buffer, const char * hardware_name,
+ const char * driver_date, GLuint agp_mode )
+{
+#define MAX_INFO 4
+ const char * cpu[MAX_INFO];
+ unsigned next = 0;
+ unsigned i;
+ unsigned offset;
+
+
+ offset = sprintf( buffer, "Mesa DRI %s %s", hardware_name, driver_date );
+
+ /* Append any AGP-specific information.
+ */
+ switch ( agp_mode ) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ offset += sprintf( & buffer[ offset ], " AGP %ux", agp_mode );
+ break;
+
+ default:
+ break;
+ }
+
+ /* Append any CPU-specific information.
+ */
+#ifdef USE_X86_ASM
+ if ( _mesa_x86_cpu_features ) {
+ cpu[next] = " x86";
+ next++;
+ }
+# ifdef USE_MMX_ASM
+ if ( cpu_has_mmx ) {
+ cpu[next] = (cpu_has_mmxext) ? "/MMX+" : "/MMX";
+ next++;
+ }
+# endif
+# ifdef USE_3DNOW_ASM
+ if ( cpu_has_3dnow ) {
+ cpu[next] = (cpu_has_3dnowext) ? "/3DNow!+" : "/3DNow!";
+ next++;
+ }
+# endif
+# ifdef USE_SSE_ASM
+ if ( cpu_has_xmm ) {
+ cpu[next] = (cpu_has_xmm2) ? "/SSE2" : "/SSE";
+ next++;
+ }
+# endif
+
+#elif defined(USE_SPARC_ASM)
+
+ cpu[0] = " SPARC";
+ next = 1;
+
+#elif defined(USE_PPC_ASM)
+ if ( _mesa_ppc_cpu_features ) {
+ cpu[next] = (cpu_has_64) ? " PowerPC 64" : " PowerPC";
+ next++;
+ }
+
+# ifdef USE_VMX_ASM
+ if ( cpu_has_vmx ) {
+ cpu[next] = "/Altivec";
+ next++;
+ }
+# endif
+
+ if ( ! cpu_has_fpu ) {
+ cpu[next] = "/No FPU";
+ next++;
+ }
+#endif
+
+ for ( i = 0 ; i < next ; i++ ) {
+ const size_t len = strlen( cpu[i] );
+
+ strncpy( & buffer[ offset ], cpu[i], len );
+ offset += len;
+ }
+
+ return offset;
+}
+
+
+
+
+#define need_GL_ARB_multisample
+#define need_GL_ARB_transpose_matrix
+#define need_GL_ARB_window_pos
+#define need_GL_EXT_compiled_vertex_array
+#define need_GL_EXT_polygon_offset
+#define need_GL_EXT_texture_object
+#define need_GL_EXT_vertex_array
+#define need_GL_MESA_window_pos
+
+/* These are needed in *all* drivers because Mesa internally implements
+ * certain functionality in terms of functions provided by these extensions.
+ * For example, glBlendFunc is implemented by calling glBlendFuncSeparateEXT.
+ */
+#define need_GL_EXT_blend_func_separate
+#define need_GL_NV_vertex_program
+
+#include "extension_helper.h"
+
+static const struct dri_extension all_mesa_extensions[] = {
+ { "GL_ARB_multisample", GL_ARB_multisample_functions },
+ { "GL_ARB_transpose_matrix", GL_ARB_transpose_matrix_functions },
+ { "GL_ARB_window_pos", GL_ARB_window_pos_functions },
+ { "GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions },
+ { "GL_EXT_compiled_vertex_array", GL_EXT_compiled_vertex_array_functions },
+ { "GL_EXT_polygon_offset", GL_EXT_polygon_offset_functions },
+ { "GL_EXT_texture_object", GL_EXT_texture_object_functions },
+ { "GL_EXT_vertex_array", GL_EXT_vertex_array_functions },
+ { "GL_MESA_window_pos", GL_MESA_window_pos_functions },
+ { "GL_NV_vertex_program", GL_NV_vertex_program_functions },
+ { NULL, NULL }
+};
+
+
+/**
+ * Enable extensions supported by the driver.
+ *
+ * \bug
+ * ARB_imaging isn't handled properly. In Mesa, enabling ARB_imaging also
+ * enables all the sub-extensions that are folded into it. This means that
+ * we need to add entry-points (via \c driInitSingleExtension) for those
+ * new functions here.
+ */
+void driInitExtensions( GLcontext * ctx,
+ const struct dri_extension * extensions_to_enable,
+ GLboolean enable_imaging )
+{
+ static int first_time = 1;
+ unsigned i;
+
+ if ( first_time ) {
+ for ( i = 0 ; i < driDispatchRemapTable_size ; i++ ) {
+ driDispatchRemapTable[i] = -1;
+ }
+
+ first_time = 0;
+ driInitExtensions( ctx, all_mesa_extensions, GL_FALSE );
+ }
+
+ if ( (ctx != NULL) && enable_imaging ) {
+ _mesa_enable_imaging_extensions( ctx );
+ }
+
+ for ( i = 0 ; extensions_to_enable[i].name != NULL ; i++ ) {
+ driInitSingleExtension( ctx, & extensions_to_enable[i] );
+ }
+}
+
+
+
+
+/**
+ * Enable and add dispatch functions for a single extension
+ *
+ * \param ctx Context where extension is to be enabled.
+ * \param ext Extension that is to be enabled.
+ *
+ * \sa driInitExtensions, _mesa_enable_extension, _glapi_add_entrypoint
+ *
+ * \todo
+ * Determine if it would be better to use \c strlen instead of the hardcoded
+ * for-loops.
+ */
+void driInitSingleExtension( GLcontext * ctx,
+ const struct dri_extension * ext )
+{
+ unsigned i;
+
+
+ if ( ext->functions != NULL ) {
+ for ( i = 0 ; ext->functions[i].strings != NULL ; i++ ) {
+ const char * functions[16];
+ const char * parameter_signature;
+ const char * str = ext->functions[i].strings;
+ unsigned j;
+ unsigned offset;
+
+
+ /* Separate the parameter signature from the rest of the string.
+ * If the parameter signature is empty (i.e., the string starts
+ * with a NUL character), then the function has a void parameter
+ * list.
+ */
+ parameter_signature = str;
+ while ( str[0] != '\0' ) {
+ str++;
+ }
+ str++;
+
+
+ /* Divide the string into the substrings that name each
+ * entry-point for the function.
+ */
+ for ( j = 0 ; j < 16 ; j++ ) {
+ if ( str[0] == '\0' ) {
+ functions[j] = NULL;
+ break;
+ }
+
+ functions[j] = str;
+
+ while ( str[0] != '\0' ) {
+ str++;
+ }
+ str++;
+ }
+
+
+ /* Add each entry-point to the dispatch table.
+ */
+ offset = _glapi_add_dispatch( functions, parameter_signature );
+ if (offset == -1) {
+ fprintf(stderr, "DISPATCH ERROR! _glapi_add_dispatch failed "
+ "to add %s!\n", functions[0]);
+ }
+ else if (ext->functions[i].remap_index != -1) {
+ driDispatchRemapTable[ ext->functions[i].remap_index ] =
+ offset;
+ }
+ else if (ext->functions[i].offset != offset) {
+ fprintf(stderr, "DISPATCH ERROR! %s -> %u != %u\n",
+ functions[0], offset, ext->functions[i].offset);
+ }
+ }
+ }
+
+ if ( ctx != NULL ) {
+ _mesa_enable_extension( ctx, ext->name );
+ }
+}
+
+
+/**
+ * Utility function used by drivers to test the versions of other components.
+ *
+ * If one of the version requirements is not met, a message is logged using
+ * \c __driUtilMessage.
+ *
+ * \param driver_name Name of the driver. Used in error messages.
+ * \param driActual Actual DRI version supplied __driCreateNewScreen.
+ * \param driExpected Minimum DRI version required by the driver.
+ * \param ddxActual Actual DDX version supplied __driCreateNewScreen.
+ * \param ddxExpected Minimum DDX minor and range of DDX major version required by the driver.
+ * \param drmActual Actual DRM version supplied __driCreateNewScreen.
+ * \param drmExpected Minimum DRM version required by the driver.
+ *
+ * \returns \c GL_TRUE if all version requirements are met. Otherwise,
+ * \c GL_FALSE is returned.
+ *
+ * \sa __driCreateNewScreen, driCheckDriDdxDrmVersions2, __driUtilMessage
+ *
+ * \todo
+ * Now that the old \c driCheckDriDdxDrmVersions function is gone, this
+ * function and \c driCheckDriDdxDrmVersions2 should be renamed.
+ */
+GLboolean
+driCheckDriDdxDrmVersions3(const char * driver_name,
+ const __DRIversion * driActual,
+ const __DRIversion * driExpected,
+ const __DRIversion * ddxActual,
+ const __DRIutilversion2 * ddxExpected,
+ const __DRIversion * drmActual,
+ const __DRIversion * drmExpected)
+{
+ static const char format[] = "%s DRI driver expected %s version %d.%d.x "
+ "but got version %d.%d.%d\n";
+ static const char format2[] = "%s DRI driver expected %s version %d-%d.%d.x "
+ "but got version %d.%d.%d\n";
+
+
+ /* Check the DRI version */
+ if ( (driActual->major != driExpected->major)
+ || (driActual->minor < driExpected->minor) ) {
+ fprintf(stderr, format, driver_name, "DRI",
+ driExpected->major, driExpected->minor,
+ driActual->major, driActual->minor, driActual->patch);
+ return GL_FALSE;
+ }
+
+ /* Check that the DDX driver version is compatible */
+ /* for miniglx we pass in -1 so we can ignore the DDX version */
+ if ( (ddxActual->major != -1) && ((ddxActual->major < ddxExpected->major_min)
+ || (ddxActual->major > ddxExpected->major_max)
+ || (ddxActual->minor < ddxExpected->minor)) ) {
+ fprintf(stderr, format2, driver_name, "DDX",
+ ddxExpected->major_min, ddxExpected->major_max, ddxExpected->minor,
+ ddxActual->major, ddxActual->minor, ddxActual->patch);
+ return GL_FALSE;
+ }
+
+ /* Check that the DRM driver version is compatible */
+ if ( (drmActual->major != drmExpected->major)
+ || (drmActual->minor < drmExpected->minor) ) {
+ fprintf(stderr, format, driver_name, "DRM",
+ drmExpected->major, drmExpected->minor,
+ drmActual->major, drmActual->minor, drmActual->patch);
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+GLboolean
+driCheckDriDdxDrmVersions2(const char * driver_name,
+ const __DRIversion * driActual,
+ const __DRIversion * driExpected,
+ const __DRIversion * ddxActual,
+ const __DRIversion * ddxExpected,
+ const __DRIversion * drmActual,
+ const __DRIversion * drmExpected)
+{
+ __DRIutilversion2 ddx_expected;
+ ddx_expected.major_min = ddxExpected->major;
+ ddx_expected.major_max = ddxExpected->major;
+ ddx_expected.minor = ddxExpected->minor;
+ ddx_expected.patch = ddxExpected->patch;
+ return driCheckDriDdxDrmVersions3(driver_name, driActual,
+ driExpected, ddxActual, & ddx_expected,
+ drmActual, drmExpected);
+}
+
+GLboolean driClipRectToFramebuffer( const GLframebuffer *buffer,
+ GLint *x, GLint *y,
+ GLsizei *width, GLsizei *height )
+{
+ /* left clipping */
+ if (*x < buffer->_Xmin) {
+ *width -= (buffer->_Xmin - *x);
+ *x = buffer->_Xmin;
+ }
+
+ /* right clipping */
+ if (*x + *width > buffer->_Xmax)
+ *width -= (*x + *width - buffer->_Xmax - 1);
+
+ if (*width <= 0)
+ return GL_FALSE;
+
+ /* bottom clipping */
+ if (*y < buffer->_Ymin) {
+ *height -= (buffer->_Ymin - *y);
+ *y = buffer->_Ymin;
+ }
+
+ /* top clipping */
+ if (*y + *height > buffer->_Ymax)
+ *height -= (*y + *height - buffer->_Ymax - 1);
+
+ if (*height <= 0)
+ return GL_FALSE;
+
+ return GL_TRUE;
+}
+
+/**
+ * Creates a set of \c __GLcontextModes that a driver will expose.
+ *
+ * A set of \c __GLcontextModes will be created based on the supplied
+ * parameters. The number of modes processed will be 2 *
+ * \c num_depth_stencil_bits * \c num_db_modes.
+ *
+ * For the most part, data is just copied from \c depth_bits, \c stencil_bits,
+ * \c db_modes, and \c visType into each \c __GLcontextModes element.
+ * However, the meanings of \c fb_format and \c fb_type require further
+ * explanation. The \c fb_format specifies which color components are in
+ * each pixel and what the default order is. For example, \c GL_RGB specifies
+ * that red, green, blue are available and red is in the "most significant"
+ * position and blue is in the "least significant". The \c fb_type specifies
+ * the bit sizes of each component and the actual ordering. For example, if
+ * \c GL_UNSIGNED_SHORT_5_6_5_REV is specified with \c GL_RGB, bits [15:11]
+ * are the blue value, bits [10:5] are the green value, and bits [4:0] are
+ * the red value.
+ *
+ * One subtle issue is the combination of \c GL_RGB or \c GL_BGR and either
+ * of the \c GL_UNSIGNED_INT_8_8_8_8 modes. The resulting mask values in the
+ * \c __GLcontextModes structure is \b identical to the \c GL_RGBA or
+ * \c GL_BGRA case, except the \c alphaMask is zero. This means that, as
+ * far as this routine is concerned, \c GL_RGB with \c GL_UNSIGNED_INT_8_8_8_8
+ * still uses 32-bits.
+ *
+ * If in doubt, look at the tables used in the function.
+ *
+ * \param ptr_to_modes Pointer to a pointer to a linked list of
+ * \c __GLcontextModes. Upon completion, a pointer to
+ * the next element to be process will be stored here.
+ * If the function fails and returns \c GL_FALSE, this
+ * value will be unmodified, but some elements in the
+ * linked list may be modified.
+ * \param fb_format Format of the framebuffer. Currently only \c GL_RGB,
+ * \c GL_RGBA, \c GL_BGR, and \c GL_BGRA are supported.
+ * \param fb_type Type of the pixels in the framebuffer. Currently only
+ * \c GL_UNSIGNED_SHORT_5_6_5,
+ * \c GL_UNSIGNED_SHORT_5_6_5_REV,
+ * \c GL_UNSIGNED_INT_8_8_8_8, and
+ * \c GL_UNSIGNED_INT_8_8_8_8_REV are supported.
+ * \param depth_bits Array of depth buffer sizes to be exposed.
+ * \param stencil_bits Array of stencil buffer sizes to be exposed.
+ * \param num_depth_stencil_bits Number of entries in both \c depth_bits and
+ * \c stencil_bits.
+ * \param db_modes Array of buffer swap modes. If an element has a
+ * value of \c GLX_NONE, then it represents a
+ * single-buffered mode. Other valid values are
+ * \c GLX_SWAP_EXCHANGE_OML, \c GLX_SWAP_COPY_OML, and
+ * \c GLX_SWAP_UNDEFINED_OML. See the
+ * GLX_OML_swap_method extension spec for more details.
+ * \param num_db_modes Number of entries in \c db_modes.
+ * \param visType GLX visual type. Usually either \c GLX_TRUE_COLOR or
+ * \c GLX_DIRECT_COLOR.
+ *
+ * \returns
+ * \c GL_TRUE on success or \c GL_FALSE on failure. Currently the only
+ * cause of failure is a bad parameter (i.e., unsupported \c fb_format or
+ * \c fb_type).
+ *
+ * \todo
+ * There is currently no way to support packed RGB modes (i.e., modes with
+ * exactly 3 bytes per pixel) or floating-point modes. This could probably
+ * be done by creating some new, private enums with clever names likes
+ * \c GL_UNSIGNED_3BYTE_8_8_8, \c GL_4FLOAT_32_32_32_32,
+ * \c GL_4HALF_16_16_16_16, etc. We can cross that bridge when we come to it.
+ */
+__DRIconfig **
+driCreateConfigs(GLenum fb_format, GLenum fb_type,
+ const u_int8_t * depth_bits, const u_int8_t * stencil_bits,
+ unsigned num_depth_stencil_bits,
+ const GLenum * db_modes, unsigned num_db_modes)
+{
+ static const u_int8_t bits_table[4][4] = {
+ /* R G B A */
+ { 3, 3, 2, 0 }, /* Any GL_UNSIGNED_BYTE_3_3_2 */
+ { 5, 6, 5, 0 }, /* Any GL_UNSIGNED_SHORT_5_6_5 */
+ { 8, 8, 8, 0 }, /* Any RGB with any GL_UNSIGNED_INT_8_8_8_8 */
+ { 8, 8, 8, 8 } /* Any RGBA with any GL_UNSIGNED_INT_8_8_8_8 */
+ };
+
+ static const u_int32_t masks_table_rgb[6][4] = {
+ { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2 */
+ { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV */
+ { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5 */
+ { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV */
+ { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000 }, /* 8_8_8_8 */
+ { 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 } /* 8_8_8_8_REV */
+ };
+
+ static const u_int32_t masks_table_rgba[6][4] = {
+ { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2 */
+ { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV */
+ { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5 */
+ { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV */
+ { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF }, /* 8_8_8_8 */
+ { 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 }, /* 8_8_8_8_REV */
+ };
+
+ static const u_int32_t masks_table_bgr[6][4] = {
+ { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */
+ { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */
+ { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5 */
+ { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV */
+ { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000 }, /* 8_8_8_8 */
+ { 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }, /* 8_8_8_8_REV */
+ };
+
+ static const u_int32_t masks_table_bgra[6][4] = {
+ { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */
+ { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */
+ { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5 */
+ { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV */
+ { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF }, /* 8_8_8_8 */
+ { 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }, /* 8_8_8_8_REV */
+ };
+
+ static const u_int8_t bytes_per_pixel[6] = {
+ 1, /* 3_3_2 */
+ 1, /* 2_3_3_REV */
+ 2, /* 5_6_5 */
+ 2, /* 5_6_5_REV */
+ 4, /* 8_8_8_8 */
+ 4 /* 8_8_8_8_REV */
+ };
+
+ const u_int8_t * bits;
+ const u_int32_t * masks;
+ int index;
+ __DRIconfig **configs, **c;
+ __GLcontextModes *modes;
+ unsigned i;
+ unsigned j;
+ unsigned k;
+ unsigned num_modes;
+ unsigned num_accum_bits = 2;
+
+ switch ( fb_type ) {
+ case GL_UNSIGNED_BYTE_3_3_2:
+ index = 0;
+ break;
+ case GL_UNSIGNED_BYTE_2_3_3_REV:
+ index = 1;
+ break;
+ case GL_UNSIGNED_SHORT_5_6_5:
+ index = 2;
+ break;
+ case GL_UNSIGNED_SHORT_5_6_5_REV:
+ index = 3;
+ break;
+ case GL_UNSIGNED_INT_8_8_8_8:
+ index = 4;
+ break;
+ case GL_UNSIGNED_INT_8_8_8_8_REV:
+ index = 5;
+ break;
+ default:
+ fprintf( stderr, "[%s:%d] Unknown framebuffer type 0x%04x.\n",
+ __FUNCTION__, __LINE__, fb_type );
+ return NULL;
+ }
+
+
+ /* Valid types are GL_UNSIGNED_SHORT_5_6_5 and GL_UNSIGNED_INT_8_8_8_8 and
+ * the _REV versions.
+ *
+ * Valid formats are GL_RGBA, GL_RGB, and GL_BGRA.
+ */
+
+ switch ( fb_format ) {
+ case GL_RGB:
+ masks = masks_table_rgb[ index ];
+ break;
+
+ case GL_RGBA:
+ masks = masks_table_rgba[ index ];
+ break;
+
+ case GL_BGR:
+ masks = masks_table_bgr[ index ];
+ break;
+
+ case GL_BGRA:
+ masks = masks_table_bgra[ index ];
+ break;
+
+ default:
+ fprintf( stderr, "[%s:%d] Unknown framebuffer format 0x%04x.\n",
+ __FUNCTION__, __LINE__, fb_format );
+ return NULL;
+ }
+
+ switch ( bytes_per_pixel[ index ] ) {
+ case 1:
+ bits = bits_table[0];
+ break;
+ case 2:
+ bits = bits_table[1];
+ break;
+ default:
+ bits = ((fb_format == GL_RGB) || (fb_format == GL_BGR))
+ ? bits_table[2]
+ : bits_table[3];
+ break;
+ }
+
+ num_modes = num_depth_stencil_bits * num_db_modes * num_accum_bits;
+ configs = _mesa_calloc((num_modes + 1) * sizeof *configs);
+ if (configs == NULL)
+ return NULL;
+
+ c = configs;
+ for ( k = 0 ; k < num_depth_stencil_bits ; k++ ) {
+ for ( i = 0 ; i < num_db_modes ; i++ ) {
+ for ( j = 0 ; j < num_accum_bits ; j++ ) {
+ *c = _mesa_malloc (sizeof **c);
+ modes = &(*c)->modes;
+ c++;
+
+ memset(modes, 0, sizeof *modes);
+ modes->redBits = bits[0];
+ modes->greenBits = bits[1];
+ modes->blueBits = bits[2];
+ modes->alphaBits = bits[3];
+ modes->redMask = masks[0];
+ modes->greenMask = masks[1];
+ modes->blueMask = masks[2];
+ modes->alphaMask = masks[3];
+ modes->rgbBits = modes->redBits + modes->greenBits
+ + modes->blueBits + modes->alphaBits;
+
+ modes->accumRedBits = 16 * j;
+ modes->accumGreenBits = 16 * j;
+ modes->accumBlueBits = 16 * j;
+ modes->accumAlphaBits = (masks[3] != 0) ? 16 * j : 0;
+ modes->visualRating = (j == 0) ? GLX_NONE : GLX_SLOW_CONFIG;
+
+ modes->stencilBits = stencil_bits[k];
+ modes->depthBits = depth_bits[k];
+
+ modes->transparentPixel = GLX_NONE;
+ modes->transparentRed = GLX_DONT_CARE;
+ modes->transparentGreen = GLX_DONT_CARE;
+ modes->transparentBlue = GLX_DONT_CARE;
+ modes->transparentAlpha = GLX_DONT_CARE;
+ modes->transparentIndex = GLX_DONT_CARE;
+ modes->visualType = GLX_DONT_CARE;
+ modes->renderType = GLX_RGBA_BIT;
+ modes->drawableType = GLX_WINDOW_BIT;
+ modes->rgbMode = GL_TRUE;
+
+ if ( db_modes[i] == GLX_NONE ) {
+ modes->doubleBufferMode = GL_FALSE;
+ }
+ else {
+ modes->doubleBufferMode = GL_TRUE;
+ modes->swapMethod = db_modes[i];
+ }
+
+ modes->haveAccumBuffer = ((modes->accumRedBits +
+ modes->accumGreenBits +
+ modes->accumBlueBits +
+ modes->accumAlphaBits) > 0);
+ modes->haveDepthBuffer = (modes->depthBits > 0);
+ modes->haveStencilBuffer = (modes->stencilBits > 0);
+
+ modes->bindToTextureRgb = GL_TRUE;
+ modes->bindToTextureRgba = GL_TRUE;
+ modes->bindToMipmapTexture = GL_FALSE;
+ modes->bindToTextureTargets = modes->rgbMode ?
+ __DRI_ATTRIB_TEXTURE_1D_BIT |
+ __DRI_ATTRIB_TEXTURE_2D_BIT |
+ __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT :
+ 0;
+ }
+ }
+ }
+ *c = NULL;
+
+ return configs;
+}
+
+const __DRIconfig **driConcatConfigs(__DRIconfig **a, __DRIconfig **b)
+{
+ const __DRIconfig **all;
+ int i, j, index;
+
+ i = 0;
+ while (a[i] != NULL)
+ i++;
+ j = 0;
+ while (b[j] != NULL)
+ j++;
+
+ all = _mesa_malloc((i + j + 1) * sizeof *all);
+ index = 0;
+ for (i = 0; a[i] != NULL; i++)
+ all[index++] = a[i];
+ for (j = 0; b[j] != NULL; j++)
+ all[index++] = b[j];
+ all[index++] = NULL;
+
+ _mesa_free(a);
+ _mesa_free(b);
+
+ return all;
+}
+
+#define __ATTRIB(attrib, field) \
+ { attrib, offsetof(__GLcontextModes, field) }
+
+static const struct { unsigned int attrib, offset; } attribMap[] = {
+ __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits),
+ __ATTRIB(__DRI_ATTRIB_LEVEL, level),
+ __ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits),
+ __ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits),
+ __ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits),
+ __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits),
+ __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits),
+ __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits),
+ __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits),
+ __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits),
+ __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits),
+ __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits),
+ __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers),
+ __ATTRIB(__DRI_ATTRIB_SAMPLES, samples),
+ __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode),
+ __ATTRIB(__DRI_ATTRIB_STEREO, stereoMode),
+ __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentPixel),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha),
+ __ATTRIB(__DRI_ATTRIB_FLOAT_MODE, floatMode),
+ __ATTRIB(__DRI_ATTRIB_RED_MASK, redMask),
+ __ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask),
+ __ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask),
+ __ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask),
+ __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth),
+ __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight),
+ __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels),
+ __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth),
+ __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight),
+ __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod),
+ __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb),
+ __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba),
+ __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture),
+ __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS, bindToTextureTargets),
+ __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted),
+
+ /* The struct field doesn't matter here, these are handled by the
+ * switch in driGetConfigAttribIndex. We need them in the array
+ * so the iterator includes them though.*/
+ __ATTRIB(__DRI_ATTRIB_RENDER_TYPE, level),
+ __ATTRIB(__DRI_ATTRIB_CONFIG_CAVEAT, level),
+ __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, level)
+};
+
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
+
+static int
+driGetConfigAttribIndex(const __DRIconfig *config,
+ unsigned int index, unsigned int *value)
+{
+ switch (attribMap[index].attrib) {
+ case __DRI_ATTRIB_RENDER_TYPE:
+ if (config->modes.rgbMode)
+ *value = __DRI_ATTRIB_RGBA_BIT;
+ else
+ *value = __DRI_ATTRIB_COLOR_INDEX_BIT;
+ break;
+ case __DRI_ATTRIB_CONFIG_CAVEAT:
+ if (config->modes.visualRating == GLX_NON_CONFORMANT_CONFIG)
+ *value = __DRI_ATTRIB_NON_CONFORMANT_CONFIG;
+ else if (config->modes.visualRating == GLX_SLOW_CONFIG)
+ *value = __DRI_ATTRIB_SLOW_BIT;
+ else
+ *value = 0;
+ break;
+ case __DRI_ATTRIB_SWAP_METHOD:
+ break;
+
+ case __DRI_ATTRIB_FLOAT_MODE:
+ *value = config->modes.floatMode;
+ break;
+
+ default:
+ *value = *(unsigned int *)
+ ((char *) &config->modes + attribMap[index].offset);
+
+ break;
+ }
+
+ return GL_TRUE;
+}
+
+int
+driGetConfigAttrib(const __DRIconfig *config,
+ unsigned int attrib, unsigned int *value)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(attribMap); i++)
+ if (attribMap[i].attrib == attrib)
+ return driGetConfigAttribIndex(config, i, value);
+
+ return GL_FALSE;
+}
+
+int
+driIndexConfigAttrib(const __DRIconfig *config, int index,
+ unsigned int *attrib, unsigned int *value)
+{
+ if (index >= 0 && index < ARRAY_SIZE(attribMap)) {
+ *attrib = attribMap[index].attrib;
+ return driGetConfigAttribIndex(config, index, value);
+ }
+
+ return GL_FALSE;
+}
diff --git a/src/VBox/Additions/common/crOpenGL/vboxdri_drv.c b/src/VBox/Additions/common/crOpenGL/vboxdri_drv.c
new file mode 100644
index 00000000..e82975e3
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/vboxdri_drv.c
@@ -0,0 +1,694 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.3
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* Minimal swrast-based dri loadable driver.
+ *
+ * Todo:
+ * -- Use malloced (rather than framebuffer) memory for backbuffer
+ * -- 32bpp is hardwired -- fix
+ *
+ * NOTES:
+ * -- No mechanism for cliprects or resize notification --
+ * assumes this is a fullscreen device.
+ * -- No locking -- assumes this is the only driver accessing this
+ * device.
+ * -- Doesn't (yet) make use of any acceleration or other interfaces
+ * provided by fb. Would be entirely happy working against any
+ * fullscreen interface.
+ * -- HOWEVER: only a small number of pixelformats are supported, and
+ * the mechanism for choosing between them makes some assumptions
+ * that may not be valid everywhere.
+ */
+
+#include "driver.h"
+#include "drm.h"
+#include "utils.h"
+#include "drirenderbuffer.h"
+
+#include "buffers.h"
+#include "extensions.h"
+#include "framebuffer.h"
+#include "renderbuffer.h"
+#include "vbo/vbo.h"
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "tnl/tnl.h"
+#include "tnl/t_context.h"
+#include "tnl/t_pipeline.h"
+#include "drivers/common/driverfuncs.h"
+
+#define need_GL_VERSION_1_3
+#define need_GL_VERSION_1_4
+#define need_GL_VERSION_1_5
+#define need_GL_VERSION_2_0
+#define need_GL_VERSION_2_1
+
+/* sw extensions for imaging */
+#define need_GL_EXT_blend_color
+#define need_GL_EXT_blend_minmax
+#define need_GL_EXT_convolution
+#define need_GL_EXT_histogram
+#define need_GL_SGI_color_table
+
+/* sw extensions not associated with some GL version */
+#define need_GL_ARB_shader_objects
+#define need_GL_ARB_vertex_program
+#define need_GL_APPLE_vertex_array_object
+#define need_GL_ATI_fragment_shader
+#define need_GL_EXT_depth_bounds_test
+#define need_GL_EXT_framebuffer_object
+#define need_GL_EXT_framebuffer_blit
+#define need_GL_EXT_gpu_program_parameters
+#define need_GL_EXT_paletted_texture
+#define need_GL_IBM_multimode_draw_arrays
+#define need_GL_MESA_resize_buffers
+#define need_GL_NV_vertex_program
+#define need_GL_NV_fragment_program
+
+#include "extension_helper.h"
+
+const struct dri_extension card_extensions[] =
+{
+ { "GL_VERSION_1_3", GL_VERSION_1_3_functions },
+ { "GL_VERSION_1_4", GL_VERSION_1_4_functions },
+ { "GL_VERSION_1_5", GL_VERSION_1_5_functions },
+ { "GL_VERSION_2_0", GL_VERSION_2_0_functions },
+ { "GL_VERSION_2_1", GL_VERSION_2_1_functions },
+
+ { "GL_EXT_blend_color", GL_EXT_blend_color_functions },
+ { "GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions },
+ { "GL_EXT_convolution", GL_EXT_convolution_functions },
+ { "GL_EXT_histogram", GL_EXT_histogram_functions },
+ { "GL_SGI_color_table", GL_SGI_color_table_functions },
+
+ { "GL_ARB_shader_objects", GL_ARB_shader_objects_functions },
+ { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions },
+ { "GL_APPLE_vertex_array_object", GL_APPLE_vertex_array_object_functions },
+ { "GL_ATI_fragment_shader", GL_ATI_fragment_shader_functions },
+ { "GL_EXT_depth_bounds_test", GL_EXT_depth_bounds_test_functions },
+ { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions },
+ { "GL_EXT_framebuffer_blit", GL_EXT_framebuffer_blit_functions },
+ { "GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions },
+ { "GL_EXT_paletted_texture", GL_EXT_paletted_texture_functions },
+ { "GL_IBM_multimode_draw_arrays", GL_IBM_multimode_draw_arrays_functions },
+ { "GL_MESA_resize_buffers", GL_MESA_resize_buffers_functions },
+ { "GL_NV_vertex_program", GL_NV_vertex_program_functions },
+ { "GL_NV_fragment_program", GL_NV_fragment_program_functions },
+ { NULL, NULL }
+};
+
+void fbSetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis);
+
+typedef struct {
+ GLcontext *glCtx; /* Mesa context */
+
+ struct {
+ __DRIcontextPrivate *context;
+ __DRIscreenPrivate *screen;
+ __DRIdrawablePrivate *drawable; /* drawable bound to this ctx */
+ } dri;
+
+} fbContext, *fbContextPtr;
+
+#define FB_CONTEXT(ctx) ((fbContextPtr)(ctx->DriverCtx))
+
+
+static const GLubyte *
+get_string(GLcontext *ctx, GLenum pname)
+{
+ (void) ctx;
+ switch (pname) {
+ case GL_RENDERER:
+ return (const GLubyte *) "Mesa dumb framebuffer";
+ default:
+ return NULL;
+ }
+}
+
+
+static void
+update_state( GLcontext *ctx, GLuint new_state )
+{
+ /* not much to do here - pass it on */
+ _swrast_InvalidateState( ctx, new_state );
+ _swsetup_InvalidateState( ctx, new_state );
+ _vbo_InvalidateState( ctx, new_state );
+ _tnl_InvalidateState( ctx, new_state );
+}
+
+
+/**
+ * Called by ctx->Driver.GetBufferSize from in core Mesa to query the
+ * current framebuffer size.
+ */
+static void
+get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ fbContextPtr fbmesa = FB_CONTEXT(ctx);
+
+ *width = fbmesa->dri.drawable->w;
+ *height = fbmesa->dri.drawable->h;
+}
+
+
+static void
+updateFramebufferSize(GLcontext *ctx)
+{
+ fbContextPtr fbmesa = FB_CONTEXT(ctx);
+ struct gl_framebuffer *fb = ctx->WinSysDrawBuffer;
+ if (fbmesa->dri.drawable->w != fb->Width ||
+ fbmesa->dri.drawable->h != fb->Height) {
+ driUpdateFramebufferSize(ctx, fbmesa->dri.drawable);
+ }
+}
+
+static void
+viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+{
+ /* XXX this should be called after we acquire the DRI lock, not here */
+ updateFramebufferSize(ctx);
+}
+
+
+static void
+init_core_functions( struct dd_function_table *functions )
+{
+ functions->GetString = get_string;
+ functions->UpdateState = update_state;
+ functions->GetBufferSize = get_buffer_size;
+ functions->Viewport = viewport;
+
+ functions->Clear = _swrast_Clear; /* could accelerate with blits */
+}
+
+
+/*
+ * Generate code for span functions.
+ */
+
+/* 24-bit BGR */
+#define NAME(PREFIX) PREFIX##_B8G8R8
+#define RB_TYPE GLubyte
+#define SPAN_VARS \
+ driRenderbuffer *drb = (driRenderbuffer *) rb;
+#define INIT_PIXEL_PTR(P, X, Y) \
+ GLubyte *P = (GLubyte *)drb->Base.Data + (drb->Base.Height - (Y)) * drb->pitch + (X) * 3;
+#define INC_PIXEL_PTR(P) P += 3
+#define STORE_PIXEL(DST, X, Y, VALUE) \
+ DST[0] = VALUE[BCOMP]; \
+ DST[1] = VALUE[GCOMP]; \
+ DST[2] = VALUE[RCOMP]
+#define FETCH_PIXEL(DST, SRC) \
+ DST[RCOMP] = SRC[2]; \
+ DST[GCOMP] = SRC[1]; \
+ DST[BCOMP] = SRC[0]; \
+ DST[ACOMP] = 0xff
+
+#include "swrast/s_spantemp.h"
+
+
+/* 32-bit BGRA */
+#define NAME(PREFIX) PREFIX##_B8G8R8A8
+#define RB_TYPE GLubyte
+#define SPAN_VARS \
+ driRenderbuffer *drb = (driRenderbuffer *) rb;
+#define INIT_PIXEL_PTR(P, X, Y) \
+ GLubyte *P = (GLubyte *)drb->Base.Data + (drb->Base.Height - (Y)) * drb->pitch + (X) * 4;
+#define INC_PIXEL_PTR(P) P += 4
+#define STORE_PIXEL(DST, X, Y, VALUE) \
+ DST[0] = VALUE[BCOMP]; \
+ DST[1] = VALUE[GCOMP]; \
+ DST[2] = VALUE[RCOMP]; \
+ DST[3] = VALUE[ACOMP]
+#define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
+ DST[0] = VALUE[BCOMP]; \
+ DST[1] = VALUE[GCOMP]; \
+ DST[2] = VALUE[RCOMP]; \
+ DST[3] = 0xff
+#define FETCH_PIXEL(DST, SRC) \
+ DST[RCOMP] = SRC[2]; \
+ DST[GCOMP] = SRC[1]; \
+ DST[BCOMP] = SRC[0]; \
+ DST[ACOMP] = SRC[3]
+
+#include "swrast/s_spantemp.h"
+
+
+/* 16-bit BGR (XXX implement dithering someday) */
+#define NAME(PREFIX) PREFIX##_B5G6R5
+#define RB_TYPE GLubyte
+#define SPAN_VARS \
+ driRenderbuffer *drb = (driRenderbuffer *) rb;
+#define INIT_PIXEL_PTR(P, X, Y) \
+ GLushort *P = (GLushort *)drb->Base.Data + (drb->Base.Height - (Y)) * drb->pitch + (X) * 2;
+#define INC_PIXEL_PTR(P) P += 1
+#define STORE_PIXEL(DST, X, Y, VALUE) \
+ DST[0] = ( (((VALUE[RCOMP]) & 0xf8) << 8) | (((VALUE[GCOMP]) & 0xfc) << 3) | ((VALUE[BCOMP]) >> 3) )
+#define FETCH_PIXEL(DST, SRC) \
+ DST[RCOMP] = ( (((SRC[0]) >> 8) & 0xf8) | (((SRC[0]) >> 11) & 0x7) ); \
+ DST[GCOMP] = ( (((SRC[0]) >> 3) & 0xfc) | (((SRC[0]) >> 5) & 0x3) ); \
+ DST[BCOMP] = ( (((SRC[0]) << 3) & 0xf8) | (((SRC[0]) ) & 0x7) ); \
+ DST[ACOMP] = 0xff
+
+#include "swrast/s_spantemp.h"
+
+
+/* 15-bit BGR (XXX implement dithering someday) */
+#define NAME(PREFIX) PREFIX##_B5G5R5
+#define RB_TYPE GLubyte
+#define SPAN_VARS \
+ driRenderbuffer *drb = (driRenderbuffer *) rb;
+#define INIT_PIXEL_PTR(P, X, Y) \
+ GLushort *P = (GLushort *)drb->Base.Data + (drb->Base.Height - (Y)) * drb->pitch + (X) * 2;
+#define INC_PIXEL_PTR(P) P += 1
+#define STORE_PIXEL(DST, X, Y, VALUE) \
+ DST[0] = ( (((VALUE[RCOMP]) & 0xf8) << 7) | (((VALUE[GCOMP]) & 0xf8) << 2) | ((VALUE[BCOMP]) >> 3) )
+#define FETCH_PIXEL(DST, SRC) \
+ DST[RCOMP] = ( (((SRC[0]) >> 7) & 0xf8) | (((SRC[0]) >> 10) & 0x7) ); \
+ DST[GCOMP] = ( (((SRC[0]) >> 2) & 0xf8) | (((SRC[0]) >> 5) & 0x7) ); \
+ DST[BCOMP] = ( (((SRC[0]) << 3) & 0xf8) | (((SRC[0]) ) & 0x7) ); \
+ DST[ACOMP] = 0xff
+
+#include "swrast/s_spantemp.h"
+
+
+/* 8-bit color index */
+#define NAME(PREFIX) PREFIX##_CI8
+#define CI_MODE
+#define RB_TYPE GLubyte
+#define SPAN_VARS \
+ driRenderbuffer *drb = (driRenderbuffer *) rb;
+#define INIT_PIXEL_PTR(P, X, Y) \
+ GLubyte *P = (GLubyte *)drb->Base.Data + (drb->Base.Height - (Y)) * drb->pitch + (X);
+#define INC_PIXEL_PTR(P) P += 1
+#define STORE_PIXEL(DST, X, Y, VALUE) \
+ *DST = VALUE[0]
+#define FETCH_PIXEL(DST, SRC) \
+ DST = SRC[0]
+
+#include "swrast/s_spantemp.h"
+
+
+
+void
+fbSetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis)
+{
+ ASSERT(drb->Base.InternalFormat == GL_RGBA);
+ if (drb->Base.InternalFormat == GL_RGBA) {
+ if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) {
+ drb->Base.GetRow = get_row_B5G6R5;
+ drb->Base.GetValues = get_values_B5G6R5;
+ drb->Base.PutRow = put_row_B5G6R5;
+ drb->Base.PutMonoRow = put_mono_row_B5G6R5;
+ drb->Base.PutRowRGB = put_row_rgb_B5G6R5;
+ drb->Base.PutValues = put_values_B5G6R5;
+ drb->Base.PutMonoValues = put_mono_values_B5G6R5;
+ }
+ else if (vis->redBits == 5 && vis->greenBits == 5 && vis->blueBits == 5) {
+ drb->Base.GetRow = get_row_B5G5R5;
+ drb->Base.GetValues = get_values_B5G5R5;
+ drb->Base.PutRow = put_row_B5G5R5;
+ drb->Base.PutMonoRow = put_mono_row_B5G5R5;
+ drb->Base.PutRowRGB = put_row_rgb_B5G5R5;
+ drb->Base.PutValues = put_values_B5G5R5;
+ drb->Base.PutMonoValues = put_mono_values_B5G5R5;
+ }
+ else if (vis->redBits == 8 && vis->greenBits == 8 && vis->blueBits == 8
+ && vis->alphaBits == 8) {
+ drb->Base.GetRow = get_row_B8G8R8A8;
+ drb->Base.GetValues = get_values_B8G8R8A8;
+ drb->Base.PutRow = put_row_B8G8R8A8;
+ drb->Base.PutMonoRow = put_mono_row_B8G8R8A8;
+ drb->Base.PutRowRGB = put_row_rgb_B8G8R8A8;
+ drb->Base.PutValues = put_values_B8G8R8A8;
+ drb->Base.PutMonoValues = put_mono_values_B8G8R8A8;
+ }
+ else if (vis->redBits == 8 && vis->greenBits == 8 && vis->blueBits == 8
+ && vis->alphaBits == 0) {
+ drb->Base.GetRow = get_row_B8G8R8;
+ drb->Base.GetValues = get_values_B8G8R8;
+ drb->Base.PutRow = put_row_B8G8R8;
+ drb->Base.PutMonoRow = put_mono_row_B8G8R8;
+ drb->Base.PutRowRGB = put_row_rgb_B8G8R8;
+ drb->Base.PutValues = put_values_B8G8R8;
+ drb->Base.PutMonoValues = put_mono_values_B8G8R8;
+ }
+ else if (vis->indexBits == 8) {
+ drb->Base.GetRow = get_row_CI8;
+ drb->Base.GetValues = get_values_CI8;
+ drb->Base.PutRow = put_row_CI8;
+ drb->Base.PutMonoRow = put_mono_row_CI8;
+ drb->Base.PutValues = put_values_CI8;
+ drb->Base.PutMonoValues = put_mono_values_CI8;
+ }
+ }
+ else {
+ /* hardware z/stencil/etc someday */
+ }
+}
+
+
+static void
+fbDestroyScreen( __DRIscreenPrivate *sPriv )
+{
+}
+
+
+static const __DRIconfig **fbFillInModes(unsigned pixel_bits,
+ unsigned depth_bits,
+ unsigned stencil_bits,
+ GLboolean have_back_buffer)
+{
+ unsigned deep = (depth_bits > 17);
+
+ /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
+ * enough to add support. Basically, if a context is created with an
+ * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
+ * will never be used.
+ */
+
+ static const GLenum db_modes[2] = { GLX_NONE, GLX_SWAP_UNDEFINED_OML };
+ uint8_t depth_bits_array[4];
+ uint8_t stencil_bits_array[4];
+ if(deep) {
+ depth_bits_array[0] = 0;
+ depth_bits_array[1] = 24;
+ stencil_bits_array[0] = 0;
+ stencil_bits_array[1] = 8;
+ } else {
+ depth_bits_array[0] = depth_bits;
+ depth_bits_array[1] = 0;
+ depth_bits_array[2] = depth_bits;
+ depth_bits_array[3] = 0;
+ stencil_bits_array[0] = 0;
+ stencil_bits_array[1] = 0;
+ stencil_bits_array[2] = 8;
+ stencil_bits_array[3] = 8;
+ }
+
+ return driCreateConfigs(
+ deep ? GL_RGBA : GL_RGB,
+ deep ? GL_UNSIGNED_INT_8_8_8_8 : GL_UNSIGNED_SHORT_5_6_5,
+ depth_bits_array,
+ stencil_bits_array,
+ deep ? 2 : 4,
+ db_modes, 2);
+}
+
+/**
+ * This is the driver specific part of the createNewScreen entry point.
+ * Called when using legacy DRI.
+ *
+ * return the __GLcontextModes supported by this driver
+ */
+static const __DRIconfig **fbInitScreen(__DRIscreenPrivate *psp)
+{
+ static const __DRIversion ddx_expected = { 1, 0, 0 };
+ static const __DRIversion dri_expected = { 4, 0, 0 };
+ static const __DRIversion drm_expected = { 1, 0, 0 };
+
+
+ if ( ! driCheckDriDdxDrmVersions2( "vboxvideo",
+ & psp->dri_version, & dri_expected,
+ & psp->ddx_version, & ddx_expected,
+ & psp->drm_version, & drm_expected ) ) {
+ return NULL;
+ }
+
+ driInitExtensions( NULL, card_extensions, GL_FALSE );
+
+ return fbFillInModes( psp->fbBPP,
+ (psp->fbBPP == 16) ? 16 : 24,
+ (psp->fbBPP == 16) ? 0 : 8,
+ 1);
+}
+
+/* Create the device specific context.
+ */
+static GLboolean
+fbCreateContext( const __GLcontextModes *glVisual,
+ __DRIcontextPrivate *driContextPriv,
+ void *sharedContextPrivate)
+{
+ fbContextPtr fbmesa;
+ GLcontext *ctx, *shareCtx;
+ struct dd_function_table functions;
+
+ assert(glVisual);
+ assert(driContextPriv);
+
+ /* Allocate the Fb context */
+ fbmesa = (fbContextPtr) _mesa_calloc( sizeof(*fbmesa) );
+ if ( !fbmesa )
+ return GL_FALSE;
+
+ /* Init default driver functions then plug in our FBdev-specific functions
+ */
+ _mesa_init_driver_functions(&functions);
+ init_core_functions(&functions);
+
+ /* Allocate the Mesa context */
+ if (sharedContextPrivate)
+ shareCtx = ((fbContextPtr) sharedContextPrivate)->glCtx;
+ else
+ shareCtx = NULL;
+
+ ctx = fbmesa->glCtx = _mesa_create_context(glVisual, shareCtx,
+ &functions, (void *) fbmesa);
+ if (!fbmesa->glCtx) {
+ _mesa_free(fbmesa);
+ return GL_FALSE;
+ }
+ driContextPriv->driverPrivate = fbmesa;
+
+ /* Create module contexts */
+ _swrast_CreateContext( ctx );
+ _vbo_CreateContext( ctx );
+ _tnl_CreateContext( ctx );
+ _swsetup_CreateContext( ctx );
+ _swsetup_Wakeup( ctx );
+
+
+ /* use default TCL pipeline */
+ {
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ tnl->Driver.RunPipeline = _tnl_run_pipeline;
+ }
+
+ _mesa_enable_sw_extensions(ctx);
+
+ return GL_TRUE;
+}
+
+
+static void
+fbDestroyContext( __DRIcontextPrivate *driContextPriv )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ fbContextPtr fbmesa = (fbContextPtr) driContextPriv->driverPrivate;
+ fbContextPtr current = ctx ? FB_CONTEXT(ctx) : NULL;
+
+ /* check if we're deleting the currently bound context */
+ if (fbmesa == current) {
+ _mesa_make_current(NULL, NULL, NULL);
+ }
+
+ /* Free fb context resources */
+ if ( fbmesa ) {
+ _swsetup_DestroyContext( fbmesa->glCtx );
+ _tnl_DestroyContext( fbmesa->glCtx );
+ _vbo_DestroyContext( fbmesa->glCtx );
+ _swrast_DestroyContext( fbmesa->glCtx );
+
+ /* free the Mesa context */
+ fbmesa->glCtx->DriverCtx = NULL;
+ _mesa_destroy_context( fbmesa->glCtx );
+
+ _mesa_free( fbmesa );
+ }
+}
+
+
+/* Create and initialize the Mesa and driver specific pixmap buffer
+ * data.
+ */
+static GLboolean
+fbCreateBuffer( __DRIscreenPrivate *driScrnPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ const __GLcontextModes *mesaVis,
+ GLboolean isPixmap )
+{
+ struct gl_framebuffer *mesa_framebuffer;
+
+ if (isPixmap) {
+ return GL_FALSE; /* not implemented */
+ }
+ else {
+ const GLboolean swDepth = mesaVis->depthBits > 0;
+ const GLboolean swAlpha = mesaVis->alphaBits > 0;
+ const GLboolean swAccum = mesaVis->accumRedBits > 0;
+ const GLboolean swStencil = mesaVis->stencilBits > 0;
+
+ mesa_framebuffer = _mesa_create_framebuffer(mesaVis);
+ if (!mesa_framebuffer)
+ return 0;
+
+ /* XXX double-check these parameters (bpp vs cpp, etc) */
+ {
+ driRenderbuffer *drb = driNewRenderbuffer(GL_RGBA,
+ driScrnPriv->pFB,
+ driScrnPriv->fbBPP / 8,
+ driScrnPriv->fbOrigin,
+ driScrnPriv->fbStride,
+ driDrawPriv);
+ fbSetSpanFunctions(drb, mesaVis);
+ _mesa_add_renderbuffer(mesa_framebuffer,
+ BUFFER_FRONT_LEFT, &drb->Base);
+ }
+ if (mesaVis->doubleBufferMode) {
+ /* XXX what are the correct origin/stride values? */
+ GLvoid *backBuf = _mesa_malloc(driScrnPriv->fbStride
+ * driScrnPriv->fbHeight);
+ driRenderbuffer *drb = driNewRenderbuffer(GL_RGBA,
+ backBuf,
+ driScrnPriv->fbBPP /8,
+ driScrnPriv->fbOrigin,
+ driScrnPriv->fbStride,
+ driDrawPriv);
+ fbSetSpanFunctions(drb, mesaVis);
+ _mesa_add_renderbuffer(mesa_framebuffer,
+ BUFFER_BACK_LEFT, &drb->Base);
+ }
+
+ _mesa_add_soft_renderbuffers(mesa_framebuffer,
+ GL_FALSE, /* color */
+ swDepth,
+ swStencil,
+ swAccum,
+ swAlpha, /* or always zero? */
+ GL_FALSE /* aux */);
+
+ driDrawPriv->driverPrivate = mesa_framebuffer;
+
+ return 1;
+ }
+}
+
+
+static void
+fbDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
+{
+ _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)));
+}
+
+
+
+/* If the backbuffer is on a videocard, this is extraordinarily slow!
+ */
+static void
+fbSwapBuffers( __DRIdrawablePrivate *dPriv )
+{
+ struct gl_framebuffer *mesa_framebuffer = (struct gl_framebuffer *)dPriv->driverPrivate;
+ struct gl_renderbuffer * front_renderbuffer = mesa_framebuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
+ void *frontBuffer = front_renderbuffer->Data;
+ int currentPitch = ((driRenderbuffer *)front_renderbuffer)->pitch;
+ void *backBuffer = mesa_framebuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer->Data;
+
+ if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
+ fbContextPtr fbmesa = (fbContextPtr) dPriv->driContextPriv->driverPrivate;
+ GLcontext *ctx = fbmesa->glCtx;
+
+ if (ctx->Visual.doubleBufferMode) {
+ int i;
+ int offset = 0;
+ char *tmp = _mesa_malloc(currentPitch);
+
+ _mesa_notifySwapBuffers( ctx ); /* flush pending rendering commands */
+
+ ASSERT(frontBuffer);
+ ASSERT(backBuffer);
+
+ for (i = 0; i < dPriv->h; i++) {
+ _mesa_memcpy(tmp, (char *) backBuffer + offset,
+ currentPitch);
+ _mesa_memcpy((char *) frontBuffer + offset, tmp,
+ currentPitch);
+ offset += currentPitch;
+ }
+
+ _mesa_free(tmp);
+ }
+ }
+ else {
+ /* XXX this shouldn't be an error but we can't handle it for now */
+ _mesa_problem(NULL, "fbSwapBuffers: drawable has no context!\n");
+ }
+}
+
+
+/* Force the context `c' to be the current context and associate with it
+ * buffer `b'.
+ */
+static GLboolean
+fbMakeCurrent( __DRIcontextPrivate *driContextPriv,
+ __DRIdrawablePrivate *driDrawPriv,
+ __DRIdrawablePrivate *driReadPriv )
+{
+ if ( driContextPriv ) {
+ fbContextPtr newFbCtx =
+ (fbContextPtr) driContextPriv->driverPrivate;
+
+ newFbCtx->dri.drawable = driDrawPriv;
+
+ _mesa_make_current( newFbCtx->glCtx,
+ driDrawPriv->driverPrivate,
+ driReadPriv->driverPrivate);
+ } else {
+ _mesa_make_current( NULL, NULL, NULL );
+ }
+
+ return GL_TRUE;
+}
+
+
+/* Force the context `c' to be unbound from its buffer.
+ */
+static GLboolean
+fbUnbindContext( __DRIcontextPrivate *driContextPriv )
+{
+ return GL_TRUE;
+}
+
+const struct __DriverAPIRec driDriverAPI = {
+ .InitScreen = fbInitScreen,
+ .DestroyScreen = fbDestroyScreen,
+ .CreateContext = fbCreateContext,
+ .DestroyContext = fbDestroyContext,
+ .CreateBuffer = fbCreateBuffer,
+ .DestroyBuffer = fbDestroyBuffer,
+ .SwapBuffers = fbSwapBuffers,
+ .MakeCurrent = fbMakeCurrent,
+ .UnbindContext = fbUnbindContext,
+};
diff --git a/src/VBox/Additions/common/crOpenGL/wgl.c b/src/VBox/Additions/common/crOpenGL/wgl.c
new file mode 100644
index 00000000..fd2ea0a3
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/wgl.c
@@ -0,0 +1,1015 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "cr_error.h"
+#include "cr_spu.h"
+#include "cr_environment.h"
+#include "cr_mem.h"
+#include "stub.h"
+
+/* I *know* most of the parameters are unused, dammit. */
+#pragma warning( disable: 4100 )
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <stdio.h>
+
+#include <iprt/cdefs.h>
+
+/* Currently host part will misbehave re-creating context with proper visual bits
+ * if contexts with alternative visual bits is requested.
+ * For now we just report a superset of all visual bits to avoid that.
+ * Better to it on the host side as well?
+ * We could also implement properly multiple pixel formats,
+ * which should be done by implementing offscreen rendering or multiple host contexts.
+ * */
+#define VBOX_CROGL_USE_VBITS_SUPERSET
+
+#ifdef VBOX_CROGL_USE_VBITS_SUPERSET
+static GLuint desiredVisual = CR_RGB_BIT | CR_ALPHA_BIT | CR_DEPTH_BIT | CR_STENCIL_BIT | CR_ACCUM_BIT | CR_DOUBLE_BIT;
+#else
+static GLuint desiredVisual = CR_RGB_BIT;
+#endif
+
+#ifndef VBOX_CROGL_USE_VBITS_SUPERSET
+/**
+ * Compute a mask of CR_*_BIT flags which reflects the attributes of
+ * the pixel format of the given hdc.
+ */
+static GLuint ComputeVisBits( HDC hdc )
+{
+ PIXELFORMATDESCRIPTOR pfd;
+ int iPixelFormat;
+ GLuint b = 0;
+
+ iPixelFormat = GetPixelFormat( hdc );
+
+ DescribePixelFormat( hdc, iPixelFormat, sizeof(pfd), &pfd );
+
+ if (pfd.cDepthBits > 0)
+ b |= CR_DEPTH_BIT;
+ if (pfd.cAccumBits > 0)
+ b |= CR_ACCUM_BIT;
+ if (pfd.cColorBits > 8)
+ b |= CR_RGB_BIT;
+ if (pfd.cStencilBits > 0)
+ b |= CR_STENCIL_BIT;
+ if (pfd.cAlphaBits > 0)
+ b |= CR_ALPHA_BIT;
+ if (pfd.dwFlags & PFD_DOUBLEBUFFER)
+ b |= CR_DOUBLE_BIT;
+ if (pfd.dwFlags & PFD_STEREO)
+ b |= CR_STEREO_BIT;
+
+ return b;
+}
+#endif
+
+DECLEXPORT(int) WINAPI wglChoosePixelFormat_prox( HDC hdc, CONST PIXELFORMATDESCRIPTOR *pfd )
+{
+ DWORD okayFlags;
+
+ CR_DDI_PROLOGUE();
+
+ stubInit();
+
+ /*
+ * NOTE!!!
+ * Here we're telling the renderspu not to use the GDI
+ * equivalent's of ChoosePixelFormat/DescribePixelFormat etc
+ * There are subtle differences in the use of these calls.
+ */
+ crSetenv("CR_WGL_DO_NOT_USE_GDI", "yes");
+
+ if ( pfd->nSize != sizeof(*pfd) || pfd->nVersion != 1 ) {
+ crError( "wglChoosePixelFormat: bad pfd\n" );
+ return 0;
+ }
+
+ okayFlags = ( PFD_DRAW_TO_WINDOW |
+ PFD_SUPPORT_GDI |
+ PFD_SUPPORT_OPENGL |
+ PFD_DOUBLEBUFFER |
+ PFD_DOUBLEBUFFER_DONTCARE |
+ PFD_SWAP_EXCHANGE |
+ PFD_SWAP_COPY |
+ /** @todo this is disabled due to VSG Open Inventor interop issues
+ * it does not make any sense actually since reporting this
+ * as well as choosing a pixel format with this cap would not do anything
+ * since ICD stuff has its own pixelformat state var */
+// PFD_STEREO |
+ PFD_STEREO_DONTCARE |
+ PFD_DEPTH_DONTCARE );
+ if ( pfd->dwFlags & ~okayFlags ) {
+ crWarning( "wglChoosePixelFormat: only support flags=0x%x, but you gave me flags=0x%x", okayFlags, pfd->dwFlags );
+ return 0;
+ }
+
+ if ( pfd->iPixelType != PFD_TYPE_RGBA ) {
+ crError( "wglChoosePixelFormat: only support RGBA\n" );
+ }
+
+ if ( pfd->cColorBits > 32 ||
+ pfd->cRedBits > 8 ||
+ pfd->cGreenBits > 8 ||
+ pfd->cBlueBits > 8 ||
+ pfd->cAlphaBits > 8 ) {
+ crWarning( "wglChoosePixelFormat: too much color precision requested\n" );
+ }
+
+ if ( pfd->dwFlags & PFD_DOUBLEBUFFER )
+ desiredVisual |= CR_DOUBLE_BIT;
+
+ if ( pfd->dwFlags & PFD_STEREO )
+ desiredVisual |= CR_STEREO_BIT;
+
+ if ( pfd->cColorBits > 8)
+ desiredVisual |= CR_RGB_BIT;
+
+ if ( pfd->cAccumBits > 0 ||
+ pfd->cAccumRedBits > 0 ||
+ pfd->cAccumGreenBits > 0 ||
+ pfd->cAccumBlueBits > 0 ||
+ pfd->cAccumAlphaBits > 0 ) {
+ crWarning( "wglChoosePixelFormat: asked for accumulation buffer, ignoring\n" );
+ }
+
+ if ( pfd->cAccumBits > 0 )
+ desiredVisual |= CR_ACCUM_BIT;
+
+ if ( pfd->cDepthBits > 32 ) {
+ crError( "wglChoosePixelFormat; asked for too many depth bits\n" );
+ }
+
+ if ( pfd->cDepthBits > 0 )
+ desiredVisual |= CR_DEPTH_BIT;
+
+ if ( pfd->cStencilBits > 8 ) {
+ crError( "wglChoosePixelFormat: asked for too many stencil bits\n" );
+ }
+
+ if ( pfd->cStencilBits > 0 )
+ desiredVisual |= CR_STENCIL_BIT;
+
+ if ( pfd->cAuxBuffers > 0 ) {
+ crError( "wglChoosePixelFormat: asked for aux buffers\n" );
+ }
+
+ if ( pfd->iLayerType != PFD_MAIN_PLANE ) {
+ crError( "wglChoosePixelFormat: asked for a strange layer\n" );
+ }
+
+ return 1;
+}
+
+DECLEXPORT(BOOL) WINAPI wglSetPixelFormat_prox( HDC hdc, int pixelFormat,
+ CONST PIXELFORMATDESCRIPTOR *pdf )
+{
+ CR_DDI_PROLOGUE();
+
+ if ( pixelFormat != 1 ) {
+ crError( "wglSetPixelFormat: pixelFormat=%d?\n", pixelFormat );
+ }
+
+ return 1;
+}
+
+DECLEXPORT(BOOL) WINAPI wglDeleteContext_prox( HGLRC hglrc )
+{
+ CR_DDI_PROLOGUE();
+ stubDestroyContext( (unsigned long) hglrc );
+ return 1;
+}
+
+DECLEXPORT(BOOL) WINAPI wglMakeCurrent_prox( HDC hdc, HGLRC hglrc )
+{
+ ContextInfo *context;
+ WindowInfo *window;
+ BOOL ret;
+
+ CR_DDI_PROLOGUE();
+
+ crHashtableLock(stub.windowTable);
+ crHashtableLock(stub.contextTable);
+
+ context = (ContextInfo *) crHashtableSearch(stub.contextTable, (unsigned long) hglrc);
+ window = stubGetWindowInfo(hdc);
+
+ if (hglrc!=0 && !context)
+ {
+ crWarning("wglMakeCurrent got unexpected hglrc 0x%x", hglrc);
+ }
+
+ ret = stubMakeCurrent( window, context );
+
+ crHashtableUnlock(stub.contextTable);
+ crHashtableUnlock(stub.windowTable);
+
+ return ret;
+}
+
+DECLEXPORT(HGLRC) WINAPI wglGetCurrentContext_prox( void )
+{
+ ContextInfo *context = stubGetCurrentContext();
+ CR_DDI_PROLOGUE();
+ return (HGLRC) (context ? context->id : 0);
+}
+
+DECLEXPORT(HDC) WINAPI wglGetCurrentDC_prox( void )
+{
+ ContextInfo *context = stubGetCurrentContext();
+ CR_DDI_PROLOGUE();
+ if (context && context->currentDrawable)
+ return (HDC) context->currentDrawable->drawable;
+ else
+ return (HDC) NULL;
+}
+
+DECLEXPORT(int) WINAPI wglGetPixelFormat_prox( HDC hdc )
+{
+ CR_DDI_PROLOGUE();
+ /* this is what we call our generic pixelformat, regardless of the HDC */
+ return 1;
+}
+
+DECLEXPORT(int) WINAPI wglDescribePixelFormat_prox( HDC hdc, int pixelFormat, UINT nBytes,
+ LPPIXELFORMATDESCRIPTOR pfd )
+{
+ CR_DDI_PROLOGUE();
+
+/* if ( pixelFormat != 1 ) {
+ * crError( "wglDescribePixelFormat: pixelFormat=%d?\n", pixelFormat );
+ * return 0;
+ * } */
+
+ if ( !pfd ) {
+ crWarning( "wglDescribePixelFormat: pfd=NULL\n" );
+ return 1; /* There's only one, baby */
+ }
+
+ if ( nBytes != sizeof(*pfd) ) {
+ crWarning( "wglDescribePixelFormat: nBytes=%u?\n", nBytes );
+ return 1; /* There's only one, baby */
+ }
+
+ pfd->nSize = sizeof(*pfd);
+ pfd->nVersion = 1;
+ pfd->dwFlags = ( PFD_DRAW_TO_WINDOW |
+ PFD_SUPPORT_GDI |
+ PFD_SUPPORT_OPENGL |
+ PFD_DOUBLEBUFFER );
+ pfd->iPixelType = PFD_TYPE_RGBA;
+ pfd->cColorBits = 32;
+ pfd->cRedBits = 8;
+ pfd->cRedShift = 24;
+ pfd->cGreenBits = 8;
+ pfd->cGreenShift = 16;
+ pfd->cBlueBits = 8;
+ pfd->cBlueShift = 8;
+ pfd->cAlphaBits = 8;
+ pfd->cAlphaShift = 0;
+ pfd->cAccumBits = 0;
+ pfd->cAccumRedBits = 0;
+ pfd->cAccumGreenBits = 0;
+ pfd->cAccumBlueBits = 0;
+ pfd->cAccumAlphaBits = 0;
+ pfd->cDepthBits = 32;
+ pfd->cStencilBits = 8;
+ pfd->cAuxBuffers = 0;
+ pfd->iLayerType = PFD_MAIN_PLANE;
+ pfd->bReserved = 0;
+ pfd->dwLayerMask = 0;
+ pfd->dwVisibleMask = 0;
+ pfd->dwDamageMask = 0;
+
+ /* the max PFD index */
+ return 1;
+}
+
+DECLEXPORT(void) WINAPI VBoxCtxChromiumParameteriCR(HGLRC hglrc, GLenum param, GLint value)
+{
+ ContextInfo *context;
+
+ CR_DDI_PROLOGUE();
+
+// crHashtableLock(stub.windowTable);
+ crHashtableLock(stub.contextTable);
+
+ context = (ContextInfo *) crHashtableSearch(stub.contextTable, (unsigned long) hglrc);
+
+ if (context)
+ {
+ stubCtxCheckCreate(context);
+ stubConChromiumParameteriCR(CR_CTX_CON(context), param, value);
+ }
+ else
+ crWarning("invalid context %#x", hglrc);
+
+ crHashtableUnlock(stub.contextTable);
+// crHashtableUnlock(stub.windowTable);
+}
+
+DECLEXPORT(BOOL) WINAPI wglShareLists_prox( HGLRC hglrc1, HGLRC hglrc2 )
+{
+ ContextInfo *context1, *context2;
+ GLint aSpuContexts[2];
+
+ CR_DDI_PROLOGUE();
+
+// crHashtableLock(stub.windowTable);
+ crHashtableLock(stub.contextTable);
+
+ context1 = (ContextInfo *) crHashtableSearch(stub.contextTable, (unsigned long) hglrc1);
+
+ if (!context1)
+ {
+ WARN(("invalid hglrc1"));
+ return FALSE;
+ }
+
+ stubCtxCheckCreate(context1);
+
+ context2 = (ContextInfo *) crHashtableSearch(stub.contextTable, (unsigned long) hglrc2);
+
+ if (!context2)
+ {
+ WARN(("invalid hglrc2"));
+ return FALSE;
+ }
+
+ stubCtxCheckCreate(context2);
+
+ aSpuContexts[0] = context1->spuContext;
+ aSpuContexts[1] = context2->spuContext;
+
+ stubConChromiumParametervCR(CR_CTX_CON(context2), GL_SHARE_LISTS_CR, GL_INT, 2, aSpuContexts);
+
+ crHashtableUnlock(stub.contextTable);
+
+ return TRUE;
+}
+
+DECLEXPORT(HGLRC) WINAPI VBoxCreateContext( HDC hdc, struct VBOXUHGSMI *pHgsmi )
+{
+ char *dpyName;
+ ContextInfo *context;
+
+ CR_DDI_PROLOGUE();
+
+ stubInit();
+
+ CRASSERT(stub.contextTable);
+
+ dpyName = crCalloc(MAX_DPY_NAME);
+ if (dpyName)
+ {
+ crMemset(dpyName, 0, MAX_DPY_NAME);
+ sprintf(dpyName, "%p", hdc);
+ }
+#ifndef VBOX_CROGL_USE_VBITS_SUPERSET
+ if (stub.haveNativeOpenGL)
+ desiredVisual |= ComputeVisBits( hdc );
+#endif
+
+ context = stubNewContext(dpyName, desiredVisual, UNDECIDED, 0
+#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
+ , pHgsmi
+#else
+ , NULL
+#endif
+ );
+ /* Not needed any more. */
+ crFree(dpyName);
+
+ if (!context)
+ return 0;
+
+ return (HGLRC) context->id;
+}
+
+DECLEXPORT(GLint) WINAPI VBoxGetWindowId( HDC hdc )
+{
+ WindowInfo *window;
+ GLint winid = 0;
+
+ CR_DDI_PROLOGUE();
+
+ crHashtableLock(stub.windowTable);
+
+ window = stubGetWindowInfo(hdc);
+ if (!window)
+ {
+ crWarning("stubGetWindowInfo: window not found!");
+ goto end;
+ }
+ if (!window->spuWindow)
+ {
+ crWarning("stubGetWindowInfo: window is null!");
+ goto end;
+ }
+
+ winid = window->spuWindow;
+
+end:
+ crHashtableUnlock(stub.windowTable);
+ return winid;
+}
+
+DECLEXPORT(GLint) WINAPI VBoxGetContextId( HGLRC hglrc )
+{
+ ContextInfo *context;
+ GLint ctxid = 0;
+
+ CR_DDI_PROLOGUE();
+
+// crHashtableLock(stub.windowTable);
+ crHashtableLock(stub.contextTable);
+
+ context = (ContextInfo *) crHashtableSearch(stub.contextTable, (unsigned long) hglrc);
+ if (!context)
+ {
+ crWarning("crHashtableSearch: context not found!");
+ goto end;
+ }
+
+ if (context->type != CHROMIUM)
+ {
+ crWarning("unexpected context type %d", context->type);
+ goto end;
+ }
+
+ if (context->spuContext <= 0)
+ {
+ crWarning("no spuSontext defined");
+ goto end;
+ }
+
+ ctxid = context->spuContext;
+
+end:
+ crHashtableUnlock(stub.contextTable);
+ return ctxid;
+}
+
+
+DECLEXPORT(HGLRC) WINAPI wglCreateContext_prox( HDC hdc )
+{
+ return VBoxCreateContext(hdc, NULL);
+}
+
+DECLEXPORT(void) WINAPI VBoxFlushToHost ( HGLRC hglrc )
+{
+ ContextInfo *context;
+
+ CR_DDI_PROLOGUE();
+
+// crHashtableLock(stub.windowTable);
+ crHashtableLock(stub.contextTable);
+
+ context = (ContextInfo *) crHashtableSearch(stub.contextTable, (unsigned long) hglrc);
+
+ if (context)
+ stubConFlush(CR_CTX_CON(context));
+ else
+ crWarning("invalid context %#x", hglrc);
+
+ crHashtableUnlock(stub.contextTable);
+// crHashtableUnlock(stub.windowTable);
+}
+
+DECLEXPORT(BOOL) WINAPI
+wglSwapBuffers_prox( HDC hdc )
+{
+ WindowInfo *window = stubGetWindowInfo(hdc);
+ CR_DDI_PROLOGUE();
+ stubSwapBuffers( window, 0 );
+ return 1;
+}
+
+DECLEXPORT(BOOL) WINAPI wglCopyContext_prox( HGLRC src, HGLRC dst, UINT mask )
+{
+ CR_DDI_PROLOGUE();
+ crWarning( "wglCopyContext: unsupported" );
+ return 0;
+}
+
+DECLEXPORT(HGLRC) WINAPI wglCreateLayerContext_prox( HDC hdc, int layerPlane )
+{
+ CR_DDI_PROLOGUE();
+ stubInit();
+ crWarning( "wglCreateLayerContext: unsupported" );
+ return 0;
+}
+
+DECLEXPORT(PROC) WINAPI wglGetProcAddress_prox( LPCSTR name )
+{
+ CR_DDI_PROLOGUE();
+ return (PROC) crGetProcAddress( name );
+}
+
+DECLEXPORT(BOOL) WINAPI wglUseFontBitmapsA_prox( HDC hdc, DWORD first, DWORD count, DWORD listBase )
+{
+ CR_DDI_PROLOGUE();
+ crWarning( "wglUseFontBitmapsA: unsupported" );
+ return 0;
+}
+
+DECLEXPORT(BOOL) WINAPI wglUseFontBitmapsW_prox( HDC hdc, DWORD first, DWORD count, DWORD listBase )
+{
+ CR_DDI_PROLOGUE();
+ crWarning( "wglUseFontBitmapsW: unsupported" );
+ return 0;
+}
+
+DECLEXPORT(BOOL) WINAPI wglDescribeLayerPlane_prox( HDC hdc, int pixelFormat, int layerPlane,
+ UINT nBytes, LPLAYERPLANEDESCRIPTOR lpd )
+{
+ CR_DDI_PROLOGUE();
+ crWarning( "wglDescribeLayerPlane: unimplemented" );
+ return 0;
+}
+
+DECLEXPORT(int) WINAPI wglSetLayerPaletteEntries_prox( HDC hdc, int layerPlane, int start,
+ int entries, CONST COLORREF *cr )
+{
+ CR_DDI_PROLOGUE();
+ crWarning( "wglSetLayerPaletteEntries: unsupported" );
+ return 0;
+}
+
+DECLEXPORT(int) WINAPI wglGetLayerPaletteEntries_prox( HDC hdc, int layerPlane, int start,
+ int entries, COLORREF *cr )
+{
+ CR_DDI_PROLOGUE();
+ crWarning( "wglGetLayerPaletteEntries: unsupported" );
+ return 0;
+}
+
+DECLEXPORT(BOOL) WINAPI wglRealizeLayerPalette_prox( HDC hdc, int layerPlane, BOOL realize )
+{
+ CR_DDI_PROLOGUE();
+ crWarning( "wglRealizeLayerPalette: unsupported" );
+ return 0;
+}
+
+DECLEXPORT(DWORD) WINAPI wglSwapMultipleBuffers_prox( UINT a, CONST void *b )
+{
+ CR_DDI_PROLOGUE();
+ crWarning( "wglSwapMultipleBuffer: unsupported" );
+ return 0;
+}
+
+DECLEXPORT(BOOL) WINAPI wglUseFontOutlinesA_prox( HDC hdc, DWORD first, DWORD count, DWORD listBase,
+ FLOAT deviation, FLOAT extrusion, int format,
+ LPGLYPHMETRICSFLOAT gmf )
+{
+ CR_DDI_PROLOGUE();
+ crWarning( "wglUseFontOutlinesA: unsupported" );
+ return 0;
+}
+
+DECLEXPORT(BOOL) WINAPI wglUseFontOutlinesW_prox( HDC hdc, DWORD first, DWORD count, DWORD listBase,
+ FLOAT deviation, FLOAT extrusion, int format,
+ LPGLYPHMETRICSFLOAT gmf )
+{
+ CR_DDI_PROLOGUE();
+ crWarning( "wglUseFontOutlinesW: unsupported" );
+ return 0;
+}
+
+DECLEXPORT(BOOL) WINAPI wglSwapLayerBuffers_prox( HDC hdc, UINT planes )
+{
+ CR_DDI_PROLOGUE();
+ if (planes == WGL_SWAP_MAIN_PLANE)
+ {
+ return wglSwapBuffers_prox(hdc);
+ }
+ else
+ {
+ crWarning( "wglSwapLayerBuffers: unsupported" );
+ return 0;
+ }
+}
+
+DECLEXPORT(BOOL) WINAPI wglChoosePixelFormatEXT_prox
+(HDC hdc, const int *piAttributes, const FLOAT *pfAttributes, UINT nMaxFormats, int *piFormats, UINT *nNumFormats)
+{
+ int *pi;
+ int wants_rgb = 0;
+
+ CR_DDI_PROLOGUE();
+
+ stubInit();
+
+ /** @todo : Need to check pfAttributes too ! */
+
+ for ( pi = (int *)piAttributes; *pi != 0; pi++ )
+ {
+ switch ( *pi )
+ {
+ case WGL_COLOR_BITS_EXT:
+ if (pi[1] > 8)
+ wants_rgb = 1;
+ pi++;
+ break;
+
+ case WGL_RED_BITS_EXT:
+ case WGL_GREEN_BITS_EXT:
+ case WGL_BLUE_BITS_EXT:
+ if (pi[1] > 3)
+ wants_rgb = 1;
+ pi++;
+ break;
+
+ case WGL_ACCUM_ALPHA_BITS_EXT:
+ case WGL_ALPHA_BITS_EXT:
+ if (pi[1] > 0)
+ desiredVisual |= CR_ALPHA_BIT;
+ pi++;
+ break;
+
+ case WGL_DOUBLE_BUFFER_EXT:
+ if (pi[1] > 0)
+ desiredVisual |= CR_DOUBLE_BIT;
+ pi++;
+ break;
+
+ case WGL_STEREO_EXT:
+ if (pi[1] > 0)
+ {
+ /** @todo this is disabled due to VSG Open Inventor interop issues
+ * it does not make any sense actually since reporting this
+ * as well as choosing a pixel format with this cap would not do anything
+ * since ICD stuff has its own pixelformat state var */
+ crWarning("WGL_STEREO_EXT not supporteed!");
+ return 0;
+// desiredVisual |= CR_STEREO_BIT;
+ }
+ pi++;
+ break;
+
+ case WGL_DEPTH_BITS_EXT:
+ if (pi[1] > 0)
+ desiredVisual |= CR_DEPTH_BIT;
+ pi++;
+ break;
+
+ case WGL_STENCIL_BITS_EXT:
+ if (pi[1] > 0)
+ desiredVisual |= CR_STENCIL_BIT;
+ pi++;
+ break;
+
+ case WGL_ACCUM_RED_BITS_EXT:
+ case WGL_ACCUM_GREEN_BITS_EXT:
+ case WGL_ACCUM_BLUE_BITS_EXT:
+ if (pi[1] > 0)
+ desiredVisual |= CR_ACCUM_BIT;
+ pi++;
+ break;
+
+ case WGL_SAMPLE_BUFFERS_EXT:
+ case WGL_SAMPLES_EXT:
+ if (pi[1] > 0)
+ {
+ /** @todo this is disabled due to VSG Open Inventor interop issues
+ * it does not make any sense actually since reporting this
+ * as well as choosing a pixel format with this cap would not do anything
+ * since ICD stuff has its own pixelformat state var */
+ crWarning("WGL_SAMPLE_BUFFERS_EXT & WGL_SAMPLES_EXT not supporteed!");
+ return 0;
+// desiredVisual |= CR_MULTISAMPLE_BIT;
+ }
+ pi++;
+ break;
+
+ case WGL_SUPPORT_OPENGL_ARB:
+ case WGL_DRAW_TO_WINDOW_ARB:
+ case WGL_ACCELERATION_ARB:
+ pi++;
+ break;
+
+ case WGL_PIXEL_TYPE_ARB:
+ if(pi[1]!=WGL_TYPE_RGBA_ARB)
+ {
+ crWarning("WGL_PIXEL_TYPE 0x%x not supported!", pi[1]);
+ return 0;
+ }
+ pi++;
+ break;
+
+ default:
+ crWarning( "wglChoosePixelFormatEXT: bad pi=0x%x", *pi );
+ return 0;
+ }
+ }
+
+ if (nNumFormats) *nNumFormats = 1;
+ if (nMaxFormats>0 && piFormats)
+ {
+ piFormats[0] = 1;
+ }
+
+ return 1;
+}
+
+DECLEXPORT(BOOL) WINAPI wglGetPixelFormatAttribivEXT_prox
+(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *pValues)
+{
+ UINT i;
+
+ CR_DDI_PROLOGUE();
+
+ if (!pValues || !piAttributes) return 0;
+
+ if ((nAttributes!=1) || (piAttributes && piAttributes[0]!=WGL_NUMBER_PIXEL_FORMATS_ARB))
+ {
+ if (iPixelFormat!=1)
+ {
+ crDebug("wglGetPixelFormatAttribivARB: bad pf:%i", iPixelFormat);
+ return 0;
+ }
+ }
+
+ for (i=0; i<nAttributes; ++i)
+ {
+ switch (piAttributes[i])
+ {
+ case WGL_NUMBER_PIXEL_FORMATS_ARB:
+ pValues[i] = 1;
+ break;
+ case WGL_DRAW_TO_WINDOW_ARB:
+ case WGL_SUPPORT_OPENGL_ARB:
+ case WGL_DOUBLE_BUFFER_ARB:
+ pValues[i] = 1;
+ break;
+ case WGL_STEREO_ARB:
+ /** @todo this is disabled due to VSG Open Inventor interop issues
+ * it does not make any sense actually since reporting this
+ * as well as choosing a pixel format with this cap would not do anything
+ * since ICD stuff has its own pixelformat state var */
+ pValues[i] = 0;
+ break;
+ case WGL_DRAW_TO_BITMAP_ARB:
+ case WGL_NEED_PALETTE_ARB:
+ case WGL_NEED_SYSTEM_PALETTE_ARB:
+ case WGL_SWAP_LAYER_BUFFERS_ARB:
+ case WGL_NUMBER_OVERLAYS_ARB:
+ case WGL_NUMBER_UNDERLAYS_ARB:
+ case WGL_TRANSPARENT_ARB:
+ case WGL_TRANSPARENT_RED_VALUE_ARB:
+ case WGL_TRANSPARENT_GREEN_VALUE_ARB:
+ case WGL_TRANSPARENT_BLUE_VALUE_ARB:
+ case WGL_TRANSPARENT_ALPHA_VALUE_ARB:
+ case WGL_TRANSPARENT_INDEX_VALUE_ARB:
+ case WGL_SHARE_DEPTH_ARB:
+ case WGL_SHARE_STENCIL_ARB:
+ case WGL_SHARE_ACCUM_ARB:
+ case WGL_SUPPORT_GDI_ARB:
+ pValues[i] = 0;
+ break;
+ case WGL_ACCELERATION_ARB:
+ pValues[i] = WGL_FULL_ACCELERATION_ARB;
+ break;
+ case WGL_SWAP_METHOD_ARB:
+ pValues[i] = WGL_SWAP_UNDEFINED_ARB;
+ break;
+ case WGL_PIXEL_TYPE_ARB:
+ pValues[i] = WGL_TYPE_RGBA_ARB;
+ break;
+ case WGL_COLOR_BITS_ARB:
+ pValues[i] = 32;
+ break;
+ case WGL_RED_BITS_ARB:
+ case WGL_GREEN_BITS_ARB:
+ case WGL_BLUE_BITS_ARB:
+ case WGL_ALPHA_BITS_ARB:
+ pValues[i] = 8;
+ break;
+ case WGL_RED_SHIFT_ARB:
+ pValues[i] = 24;
+ break;
+ case WGL_GREEN_SHIFT_ARB:
+ pValues[i] = 16;
+ break;
+ case WGL_BLUE_SHIFT_ARB:
+ pValues[i] = 8;
+ break;
+ case WGL_ALPHA_SHIFT_ARB:
+ pValues[i] = 0;
+ break;
+ case WGL_ACCUM_BITS_ARB:
+ pValues[i] = 0;
+ break;
+ case WGL_ACCUM_RED_BITS_ARB:
+ pValues[i] = 0;
+ break;
+ case WGL_ACCUM_GREEN_BITS_ARB:
+ pValues[i] = 0;
+ break;
+ case WGL_ACCUM_BLUE_BITS_ARB:
+ pValues[i] = 0;
+ break;
+ case WGL_ACCUM_ALPHA_BITS_ARB:
+ pValues[i] = 0;
+ break;
+ case WGL_DEPTH_BITS_ARB:
+ pValues[i] = 32;
+ break;
+ case WGL_STENCIL_BITS_ARB:
+ pValues[i] = 8;
+ break;
+ case WGL_AUX_BUFFERS_ARB:
+ pValues[i] = 0;
+ break;
+ case WGL_SAMPLE_BUFFERS_EXT:
+ /** @todo this is disabled due to VSG Open Inventor interop issues
+ * it does not make any sense actually since reporting this
+ * as well as choosing a pixel format with this cap would not do anything
+ * since ICD stuff has its own pixelformat state var */
+ pValues[i] = 0;
+ break;
+ case WGL_SAMPLES_EXT:
+ /** @todo this is disabled due to VSG Open Inventor interop issues
+ * it does not make any sense actually since reporting this
+ * as well as choosing a pixel format with this cap would not do anything
+ * since ICD stuff has its own pixelformat state var */
+ pValues[i] = 0;
+ break;
+ case 0x202d: /* <- WGL_DRAW_TO_PBUFFER_ARB this is to make VSG Open Inventor happy */
+ pValues[i] = 0;
+ break;
+ default:
+ crWarning("wglGetPixelFormatAttribivARB: bad attrib=0x%x", piAttributes[i]);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+DECLEXPORT(BOOL) WINAPI wglGetPixelFormatAttribfvEXT_prox
+(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, float *pValues)
+{
+ UINT i;
+
+ CR_DDI_PROLOGUE();
+
+ if (!pValues || !piAttributes) return 0;
+
+ if ((nAttributes!=1) || (piAttributes && piAttributes[0]!=WGL_NUMBER_PIXEL_FORMATS_ARB))
+ {
+ if (iPixelFormat!=1)
+ {
+ crDebug("wglGetPixelFormatAttribivARB: bad pf:%i", iPixelFormat);
+ return 0;
+ }
+ }
+
+ for (i=0; i<nAttributes; ++i)
+ {
+ switch (piAttributes[i])
+ {
+ case WGL_NUMBER_PIXEL_FORMATS_ARB:
+ pValues[i] = 1.f;
+ break;
+ case WGL_DRAW_TO_WINDOW_ARB:
+ case WGL_SUPPORT_OPENGL_ARB:
+ case WGL_DOUBLE_BUFFER_ARB:
+ pValues[i] = 1.f;
+ break;
+ case WGL_STEREO_ARB:
+ /** @todo this is disabled due to VSG Open Inventor interop issues
+ * it does not make any sense actually since reporting this
+ * as well as choosing a pixel format with this cap would not do anything
+ * since ICD stuff has its own pixelformat state var */
+ pValues[i] = 0.f;
+ break;
+ case WGL_DRAW_TO_BITMAP_ARB:
+ case WGL_NEED_PALETTE_ARB:
+ case WGL_NEED_SYSTEM_PALETTE_ARB:
+ case WGL_SWAP_LAYER_BUFFERS_ARB:
+ case WGL_NUMBER_OVERLAYS_ARB:
+ case WGL_NUMBER_UNDERLAYS_ARB:
+ case WGL_TRANSPARENT_ARB:
+ case WGL_TRANSPARENT_RED_VALUE_ARB:
+ case WGL_TRANSPARENT_GREEN_VALUE_ARB:
+ case WGL_TRANSPARENT_BLUE_VALUE_ARB:
+ case WGL_TRANSPARENT_ALPHA_VALUE_ARB:
+ case WGL_TRANSPARENT_INDEX_VALUE_ARB:
+ case WGL_SHARE_DEPTH_ARB:
+ case WGL_SHARE_STENCIL_ARB:
+ case WGL_SHARE_ACCUM_ARB:
+ case WGL_SUPPORT_GDI_ARB:
+ pValues[i] = 0.f;
+ break;
+ case WGL_ACCELERATION_ARB:
+ pValues[i] = WGL_FULL_ACCELERATION_ARB;
+ break;
+ case WGL_SWAP_METHOD_ARB:
+ pValues[i] = WGL_SWAP_UNDEFINED_ARB;
+ break;
+ case WGL_PIXEL_TYPE_ARB:
+ pValues[i] = WGL_TYPE_RGBA_ARB;
+ break;
+ case WGL_COLOR_BITS_ARB:
+ pValues[i] = 32.f;
+ break;
+ case WGL_RED_BITS_ARB:
+ case WGL_GREEN_BITS_ARB:
+ case WGL_BLUE_BITS_ARB:
+ case WGL_ALPHA_BITS_ARB:
+ pValues[i] = 8.f;
+ break;
+ case WGL_RED_SHIFT_ARB:
+ pValues[i] = 24.f;
+ break;
+ case WGL_GREEN_SHIFT_ARB:
+ pValues[i] = 16.f;
+ break;
+ case WGL_BLUE_SHIFT_ARB:
+ pValues[i] = 8.f;
+ break;
+ case WGL_ALPHA_SHIFT_ARB:
+ pValues[i] = 0.f;
+ break;
+ case WGL_ACCUM_BITS_ARB:
+ pValues[i] = 0.f;
+ break;
+ case WGL_ACCUM_RED_BITS_ARB:
+ pValues[i] = 0.f;
+ break;
+ case WGL_ACCUM_GREEN_BITS_ARB:
+ pValues[i] = 0.f;
+ break;
+ case WGL_ACCUM_BLUE_BITS_ARB:
+ pValues[i] = 0.f;
+ break;
+ case WGL_ACCUM_ALPHA_BITS_ARB:
+ pValues[i] = 0.f;
+ break;
+ case WGL_DEPTH_BITS_ARB:
+ pValues[i] = 32.f;
+ break;
+ case WGL_STENCIL_BITS_ARB:
+ pValues[i] = 8.f;
+ break;
+ case WGL_AUX_BUFFERS_ARB:
+ pValues[i] = 0.f;
+ break;
+ case WGL_SAMPLE_BUFFERS_EXT:
+ /** @todo this is disabled due to VSG Open Inventor interop issues
+ * it does not make any sense actually since reporting this
+ * as well as choosing a pixel format with this cap would not do anything
+ * since ICD stuff has its own pixelformat state var */
+ pValues[i] = 0.f;
+ break;
+ case WGL_SAMPLES_EXT:
+ /** @todo this is disabled due to VSG Open Inventor interop issues
+ * it does not make any sense actually since reporting this
+ * as well as choosing a pixel format with this cap would not do anything
+ * since ICD stuff has its own pixelformat state var */
+ pValues[i] = 0.f;
+ break;
+ case 0x202d: /* <- WGL_DRAW_TO_PBUFFER_ARB this is to make VSG Open Inventor happy */
+ pValues[i] = 0.f;
+ break;
+ default:
+ crWarning("wglGetPixelFormatAttribivARB: bad attrib=0x%x", piAttributes[i]);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+DECLEXPORT(BOOL) WINAPI wglSwapIntervalEXT_prox(int interval)
+{
+ CR_DDI_PROLOGUE();
+ return TRUE;
+}
+
+DECLEXPORT(int) WINAPI wglGetSwapIntervalEXT_prox()
+{
+ CR_DDI_PROLOGUE();
+ return 1;
+}
+
+static GLubyte *gsz_wgl_extensions = "WGL_EXT_pixel_format WGL_ARB_pixel_format WGL_ARB_multisample";
+
+DECLEXPORT(const GLubyte *) WINAPI wglGetExtensionsStringEXT_prox()
+{
+ CR_DDI_PROLOGUE();
+ return gsz_wgl_extensions;
+}
+
+DECLEXPORT(const GLubyte *) WINAPI wglGetExtensionsStringARB_prox(HDC hdc)
+{
+ CR_DDI_PROLOGUE();
+ (void) hdc;
+
+ return gsz_wgl_extensions;
+}
diff --git a/src/VBox/Additions/common/crOpenGL/windows_exports.py b/src/VBox/Additions/common/crOpenGL/windows_exports.py
new file mode 100755
index 00000000..974d482e
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/windows_exports.py
@@ -0,0 +1,98 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+
+def GenerateEntrypoints():
+
+ apiutil.CopyrightC()
+
+ print('#include "chromium.h"')
+ print('#include "stub.h"')
+ print('')
+ print('#define NAKED __declspec(naked)')
+ print('#define UNUSED(x) ((void)(x))')
+ print('')
+
+
+ # Get sorted list of dispatched functions.
+ # The order is very important - it must match cr_opcodes.h
+ # and spu_dispatch_table.h
+ keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+ for index in range(len(keys)):
+ func_name = keys[index]
+ if apiutil.Category(func_name) == "Chromium":
+ continue
+ if apiutil.Category(func_name) == "VBox":
+ continue
+
+ return_type = apiutil.ReturnType(func_name)
+ params = apiutil.Parameters(func_name)
+
+ print("NAKED %s cr_gl%s(%s)" % (return_type, func_name,
+ apiutil.MakeDeclarationString( params )))
+ print("{")
+ print("\t__asm jmp [glim.%s]" % func_name)
+ for (name, type, vecSize) in params:
+ print("\tUNUSED(%s);" % name)
+ print("}")
+ print("")
+
+ print('/*')
+ print('* Aliases')
+ print('*/')
+
+ # Now loop over all the functions and take care of any aliases
+ allkeys = apiutil.GetAllFunctions(sys.argv[1]+"/APIspec.txt")
+ for func_name in allkeys:
+ if "omit" in apiutil.ChromiumProps(func_name):
+ continue
+
+ if func_name in keys:
+ # we already processed this function earlier
+ continue
+
+ # alias is the function we're aliasing
+ alias = apiutil.Alias(func_name)
+ if alias:
+ return_type = apiutil.ReturnType(func_name)
+ params = apiutil.Parameters(func_name)
+ print("NAKED %s cr_gl%s(%s)" % (return_type, func_name,
+ apiutil.MakeDeclarationString( params )))
+ print("{")
+ print("\t__asm jmp [glim.%s]" % alias)
+ for (name, type, vecSize) in params:
+ print("\tUNUSED(%s);" % name)
+ print("}")
+ print("")
+
+
+ print('/*')
+ print('* No-op stubs')
+ print('*/')
+
+ # Now generate no-op stub functions
+ for func_name in allkeys:
+ if "stub" in apiutil.ChromiumProps(func_name):
+ return_type = apiutil.ReturnType(func_name)
+ params = apiutil.Parameters(func_name)
+ print("NAKED %s cr_gl%s(%s)" % (return_type, func_name, apiutil.MakeDeclarationString(params)))
+ print("{")
+ if return_type != "void":
+ print("return (%s) 0" % return_type)
+ print("}")
+ print("")
+
+
+
+
+GenerateEntrypoints()
+
diff --git a/src/VBox/Additions/common/crOpenGL/windows_getprocaddress.py b/src/VBox/Additions/common/crOpenGL/windows_getprocaddress.py
new file mode 100755
index 00000000..0899d9d9
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/windows_getprocaddress.py
@@ -0,0 +1,171 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+apiutil.CopyrightC()
+
+print("""
+/* DO NOT EDIT - THIS FILE GENERATED BY THE getprocaddress.py SCRIPT */
+#include "chromium.h"
+#include "cr_string.h"
+#include "cr_version.h"
+#include "stub.h"
+#include "icd_drv.h"
+#include "cr_gl.h"
+#include "cr_error.h"
+
+#ifdef WINDOWS
+#pragma warning( disable: 4055 )
+#endif
+
+""")
+
+print("""
+struct name_address {
+ const char *name;
+ CR_PROC address;
+};
+
+PROC WINAPI wglGetProcAddress_prox( LPCSTR name );
+
+static struct name_address functions[] = {
+""")
+
+
+keys = apiutil.GetAllFunctionsAndOmittedAliases(sys.argv[1]+"/APIspec.txt")
+for func_name in keys:
+ if "Chromium" == apiutil.Category(func_name):
+ continue
+ if "VBox" == apiutil.Category(func_name):
+ continue
+ if func_name == "BoundsInfoCR":
+ continue
+ if "GL_chromium" == apiutil.Category(func_name):
+ pass #continue
+
+ # alias is the function we're aliasing
+ proc_name = func_name
+ if "omit" in apiutil.ChromiumProps(func_name):
+ alias = apiutil.Alias(func_name)
+ if alias:
+ proc_name = alias
+
+ wrap = apiutil.GetCategoryWrapper(func_name)
+ name = "gl" + func_name
+ address = "cr_gl" + proc_name
+ if wrap:
+ print('#ifdef CR_%s' % wrap)
+ print('\t{ "%s", (CR_PROC) %s },' % (name, address))
+ if wrap:
+ print('#endif')
+
+
+print("\t/* Chromium binding/glue functions */")
+
+for func_name in keys:
+ if (func_name == "Writeback" or
+ func_name == "BoundsInfoCR" or
+ func_name == "GetUniformsLocations" or
+ func_name == "GetAttribsLocations"):
+ continue
+ if apiutil.Category(func_name) == "Chromium":
+ print('\t{ "cr%s", (CR_PROC) cr%s },' % (func_name, func_name))
+
+print("\t/* Windows ICD functions */")
+
+for func_name in ( "CopyContext",
+ "CreateContext",
+ "CreateLayerContext",
+ "DeleteContext",
+ "DescribeLayerPlane",
+ "DescribePixelFormat",
+ "GetLayerPaletteEntries",
+ "RealizeLayerPalette",
+ "SetLayerPaletteEntries",
+ "SetPixelFormat",
+ "ShareLists",
+ "SwapBuffers",
+ "SwapLayerBuffers",
+ "ReleaseContext",
+ "SetContext",
+ "ValidateVersion"):
+ print('\t{ "Drv%s", (CR_PROC) Drv%s },' % (func_name, func_name))
+
+print('\t{ "DrvGetProcAddress", (CR_PROC) wglGetProcAddress_prox },')
+
+print("""
+ { NULL, NULL }
+};
+
+extern const GLubyte * WINAPI wglGetExtensionsStringEXT_prox(void);
+extern const GLubyte * WINAPI wglGetExtensionsStringARB_prox(HDC hdc);
+extern BOOL WINAPI wglChoosePixelFormatEXT_prox(HDC hdc, const int *piAttributes, const FLOAT *pfAttributes, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
+extern BOOL WINAPI wglGetPixelFormatAttribivEXT_prox(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *pValues);
+extern BOOL WINAPI wglGetPixelFormatAttribfvEXT_prox(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, float *pValues);
+
+BOOL WINAPI wglSwapIntervalEXT(int interval)
+{
+ return false;
+}
+
+CR_PROC CR_APIENTRY crGetProcAddress( const char *name )
+{
+ int i;
+ wglGetExtensionsStringEXTFunc_t wglGetExtensionsStringEXT = wglGetExtensionsStringEXT_prox;
+ wglGetExtensionsStringARBFunc_t wglGetExtensionsStringARB = wglGetExtensionsStringARB_prox;
+ wglChoosePixelFormatEXTFunc_t wglChoosePixelFormatEXT = wglChoosePixelFormatEXT_prox;
+ wglGetPixelFormatAttribivEXTFunc_t wglGetPixelFormatAttribivEXT = wglGetPixelFormatAttribivEXT_prox;
+ wglGetPixelFormatAttribfvEXTFunc_t wglGetPixelFormatAttribfvEXT = wglGetPixelFormatAttribfvEXT_prox;
+
+ stubInit();
+
+ for (i = 0; functions[i].name; i++) {
+ if (crStrcmp(name, functions[i].name) == 0) {
+ /*crDebug("crGetProcAddress(%s) returns %p", name, functions[i].address);*/
+ return functions[i].address;
+ }
+ }
+
+ if (!crStrcmp(name, "wglGetExtensionsStringEXT")) return (CR_PROC) wglGetExtensionsStringEXT;
+ if (!crStrcmp(name, "wglGetExtensionsStringARB")) return (CR_PROC) wglGetExtensionsStringARB;
+
+ if (!crStrcmp(name, "wglChoosePixelFormatEXT")) return (CR_PROC) wglChoosePixelFormatEXT;
+ if (!crStrcmp(name, "wglGetPixelFormatAttribivEXT")) return (CR_PROC) wglGetPixelFormatAttribivEXT;
+ if (!crStrcmp(name, "wglGetPixelFormatAttribfvEXT")) return (CR_PROC) wglGetPixelFormatAttribfvEXT;
+
+ if (!crStrcmp(name, "wglChoosePixelFormatARB")) return (CR_PROC) wglChoosePixelFormatEXT;
+ if (!crStrcmp(name, "wglGetPixelFormatAttribivARB")) return (CR_PROC) wglGetPixelFormatAttribivEXT;
+ if (!crStrcmp(name, "wglGetPixelFormatAttribfvARB")) return (CR_PROC) wglGetPixelFormatAttribfvEXT;
+
+ if (!crStrcmp(name, "wglSwapIntervalEXT")) return (CR_PROC) wglSwapIntervalEXT;
+
+ crDebug("Returning GetProcAddress:NULL for %s", name);
+ return NULL;
+}
+
+""")
+
+
+
+# XXX should crGetProcAddress really handle WGL/GLX functions???
+print_foo = """
+/* As these are Windows specific (i.e. wgl), define these now.... */
+#ifdef WINDOWS
+ {
+ wglGetExtensionsStringEXTFunc_t wglGetExtensionsStringEXT = NULL;
+ wglChoosePixelFormatFunc_t wglChoosePixelFormatEXT = NULL;
+ wglGetPixelFormatAttribivEXTFunc_t wglGetPixelFormatAttribivEXT = NULL;
+ wglGetPixelFormatAttribfvEXTFunc_t wglGetPixelFormatAttribfvEXT = NULL;
+ if (!crStrcmp(name, "wglGetExtensionsStringEXT")) return (CR_PROC) wglGetExtensionsStringEXT;
+ if (!crStrcmp(name, "wglChoosePixelFormatEXT")) return (CR_PROC) wglChoosePixelFormatEXT;
+ if (!crStrcmp(name, "wglGetPixelFormatAttribivEXT")) return (CR_PROC) wglGetPixelFormatAttribivEXT;
+ if (!crStrcmp(name, "wglGetPixelFormatAttribfvEXT")) return (CR_PROC) wglGetPixelFormatAttribfvEXT;
+ }
+#endif
+"""
diff --git a/src/VBox/Additions/common/crOpenGL/windows_i386_exports.py b/src/VBox/Additions/common/crOpenGL/windows_i386_exports.py
new file mode 100755
index 00000000..5a4e744e
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/windows_i386_exports.py
@@ -0,0 +1,95 @@
+# Copyright (c) 2001, Stanford University
+# All rights reserved.
+#
+# See the file LICENSE.txt for information on redistributing this software.
+
+
+from __future__ import print_function
+import sys
+
+import apiutil
+
+
+def GenerateEntrypoints():
+
+ #apiutil.CopyrightC()
+ print('%include "iprt/asmdefs.mac"')
+ print("")
+ print("%ifdef RT_ARCH_AMD64")
+ print("extern glim")
+ print("%else ; X86")
+ print("extern _glim")
+ print("%endif")
+ print("")
+
+ # Get sorted list of dispatched functions.
+ # The order is very important - it must match cr_opcodes.h
+ # and spu_dispatch_table.h
+ keys = apiutil.GetDispatchedFunctions(sys.argv[1]+"/APIspec.txt")
+
+ for index in range(len(keys)):
+ func_name = keys[index]
+ if apiutil.Category(func_name) == "Chromium":
+ continue
+ if apiutil.Category(func_name) == "VBox":
+ continue
+
+ print("BEGINPROC_EXPORTED cr_gl%s" % func_name)
+ print("%ifdef RT_ARCH_AMD64")
+ print("\tmov \trax, qword glim+%d" % (8*index))
+ print("\tjmp \t[rax]")
+ print("%else ; X86")
+ print("\tmov \teax, dword _glim+%d" % (4*index))
+ print("\tjmp \t[eax]")
+ print("%endif")
+ print("ENDPROC cr_gl%s" % func_name)
+ print("")
+
+
+ print(';')
+ print('; Aliases')
+ print(';')
+
+ # Now loop over all the functions and take care of any aliases
+ allkeys = apiutil.GetAllFunctions(sys.argv[1]+"/APIspec.txt")
+ for func_name in allkeys:
+ if "omit" in apiutil.ChromiumProps(func_name):
+ continue
+
+ if func_name in keys:
+ # we already processed this function earlier
+ continue
+
+ # alias is the function we're aliasing
+ alias = apiutil.Alias(func_name)
+ if alias:
+ # this dict lookup should never fail (raise an exception)!
+ index = keys.index(alias)
+ print("BEGINPROC_EXPORTED cr_gl%s" % func_name)
+ print("%ifdef RT_ARCH_AMD64")
+ print("\tmov \trax, qword glim+%d" % (8*index))
+ print("\tjmp \t[rax]")
+ print("%else ; X86")
+ print("\tmov \teax, dword _glim+%d" % (4*index))
+ print("\tjmp \t[eax]")
+ print("%endif")
+ print("ENDPROC cr_gl%s" % func_name)
+ print("")
+
+
+ print(';')
+ print('; No-op stubs')
+ print(';')
+
+ # Now generate no-op stub functions
+ for func_name in allkeys:
+ if "stub" in apiutil.ChromiumProps(func_name):
+ print("BEGINPROC_EXPORTED cr_gl%s" % func_name)
+ print("\tleave")
+ print("\tret")
+ print("ENDPROC cr_gl%s" % func_name)
+ print("")
+
+
+GenerateEntrypoints()
+
diff --git a/src/VBox/Additions/common/crOpenGL/xfont.c b/src/VBox/Additions/common/crOpenGL/xfont.c
new file mode 100644
index 00000000..9451fa4a
--- /dev/null
+++ b/src/VBox/Additions/common/crOpenGL/xfont.c
@@ -0,0 +1,244 @@
+/* Copyright (c) 2001, Stanford University
+ * All rights reserved
+ *
+ * See the file LICENSE.txt for information on redistributing this software.
+ */
+
+#include "chromium.h"
+#include "cr_error.h"
+#include "cr_mem.h"
+#include "stub.h"
+
+/** code borrowed from Mesa */
+
+
+/** Fill a BITMAP with a character C from thew current font
+ in the graphics context GC. WIDTH is the width in bytes
+ and HEIGHT is the height in bits.
+
+ Note that the generated bitmaps must be used with
+
+ glPixelStorei (GL_UNPACK_SWAP_BYTES, GL_FALSE);
+ glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE);
+ glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
+ glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
+
+ Possible optimizations:
+
+ * use only one reusable pixmap with the maximum dimensions.
+ * draw the entire font into a single pixmap (careful with
+ proportional fonts!).
+*/
+
+
+/**
+ * Generate OpenGL-compatible bitmap.
+ */
+static void
+fill_bitmap(Display *dpy, Window win, GC gc,
+ unsigned int width, unsigned int height,
+ int x0, int y0, unsigned int c, GLubyte *bitmap)
+{
+ XImage *image;
+ unsigned int x, y;
+ Pixmap pixmap;
+ XChar2b char2b;
+
+ pixmap = XCreatePixmap(dpy, win, 8*width, height, 1);
+ XSetForeground(dpy, gc, 0);
+ XFillRectangle(dpy, pixmap, gc, 0, 0, 8*width, height);
+ XSetForeground(dpy, gc, 1);
+
+ char2b.byte1 = (c >> 8) & 0xff;
+ char2b.byte2 = (c & 0xff);
+
+ XDrawString16(dpy, pixmap, gc, x0, y0, &char2b, 1);
+
+ image = XGetImage(dpy, pixmap, 0, 0, 8*width, height, 1, XYPixmap);
+ if (image) {
+ /* Fill the bitmap (X11 and OpenGL are upside down wrt each other). */
+ for (y = 0; y < height; y++)
+ for (x = 0; x < 8*width; x++)
+ if (XGetPixel(image, x, y))
+ bitmap[width*(height - y - 1) + x/8] |= (1 << (7 - (x % 8)));
+ XDestroyImage(image);
+ }
+
+ XFreePixmap(dpy, pixmap);
+}
+
+/*
+ * determine if a given glyph is valid and return the
+ * corresponding XCharStruct.
+ */
+static XCharStruct *isvalid(XFontStruct *fs, unsigned int which)
+{
+ unsigned int rows, pages;
+ unsigned int byte1 = 0, byte2 = 0;
+ int i, valid = 1;
+
+ rows = fs->max_byte1 - fs->min_byte1 + 1;
+ pages = fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1;
+
+ if (rows == 1) {
+ /* "linear" fonts */
+ if ((fs->min_char_or_byte2 > which) ||
+ (fs->max_char_or_byte2 < which)) valid = 0;
+ }
+ else {
+ /* "matrix" fonts */
+ byte2 = which & 0xff;
+ byte1 = which >> 8;
+ if ((fs->min_char_or_byte2 > byte2) ||
+ (fs->max_char_or_byte2 < byte2) ||
+ (fs->min_byte1 > byte1) ||
+ (fs->max_byte1 < byte1)) valid = 0;
+ }
+
+ if (valid) {
+ if (fs->per_char) {
+ if (rows == 1) {
+ /* "linear" fonts */
+ return fs->per_char + (which-fs->min_char_or_byte2);
+ }
+ else {
+ /* "matrix" fonts */
+ i = ((byte1 - fs->min_byte1) * pages) +
+ (byte2 - fs->min_char_or_byte2);
+ return fs->per_char + i;
+ }
+ }
+ else {
+ return &fs->min_bounds;
+ }
+ }
+ return NULL;
+}
+
+
+void stubUseXFont( Display *dpy, Font font, int first, int count, int listbase )
+{
+ Window win;
+ Pixmap pixmap;
+ GC gc;
+ XGCValues values;
+ unsigned long valuemask;
+ XFontStruct *fs;
+ GLint swapbytes, lsbfirst, rowlength;
+ GLint skiprows, skippixels, alignment;
+ unsigned int max_width, max_height, max_bm_width, max_bm_height;
+ GLubyte *bm;
+ int i;
+
+ win = RootWindow(dpy, DefaultScreen(dpy));
+
+ fs = XQueryFont(dpy, font);
+ if (!fs) {
+ crWarning("Couldn't get font structure information");
+ return;
+ }
+
+ /* Allocate a bitmap that can fit all characters. */
+ max_width = fs->max_bounds.rbearing - fs->min_bounds.lbearing;
+ max_height = fs->max_bounds.ascent + fs->max_bounds.descent;
+ max_bm_width = (max_width + 7) / 8;
+ max_bm_height = max_height;
+
+ bm = (GLubyte *) crAlloc((max_bm_width * max_bm_height) * sizeof(GLubyte));
+ if (!bm) {
+ XFreeFontInfo( NULL, fs, 1 );
+ crWarning("Couldn't allocate bitmap in glXUseXFont()");
+ return;
+ }
+
+ /* Save the current packing mode for bitmaps. */
+ glGetIntegerv(GL_UNPACK_SWAP_BYTES, &swapbytes);
+ glGetIntegerv(GL_UNPACK_LSB_FIRST, &lsbfirst);
+ glGetIntegerv(GL_UNPACK_ROW_LENGTH, &rowlength);
+ glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skiprows);
+ glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skippixels);
+ glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
+
+ /* Enforce a standard packing mode which is compatible with
+ fill_bitmap() from above. This is actually the default mode,
+ except for the (non)alignment. */
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ pixmap = XCreatePixmap(dpy, win, 10, 10, 1);
+ values.foreground = BlackPixel(dpy, DefaultScreen (dpy));
+ values.background = WhitePixel(dpy, DefaultScreen (dpy));
+ values.font = fs->fid;
+ valuemask = GCForeground | GCBackground | GCFont;
+ gc = XCreateGC(dpy, pixmap, valuemask, &values);
+ XFreePixmap(dpy, pixmap);
+
+ for (i = 0; i < count; i++) {
+ unsigned int width, height, bm_width, bm_height;
+ GLfloat x0, y0, dx, dy;
+ XCharStruct *ch;
+ int x, y;
+ unsigned int c = first + i;
+ int list = listbase + i;
+ int valid;
+
+ /* check on index validity and get the bounds */
+ ch = isvalid(fs, c);
+ if (!ch) {
+ ch = &fs->max_bounds;
+ valid = 0;
+ }
+ else {
+ valid = 1;
+ }
+
+ /* glBitmap()' parameters:
+ straight from the glXUseXFont(3) manpage. */
+ width = ch->rbearing - ch->lbearing;
+ height = ch->ascent + ch->descent;
+ x0 = -ch->lbearing;
+ y0 = ch->descent - 0; /* XXX used to subtract 1 here */
+ /* but that caused a conformance failure */
+ dx = ch->width;
+ dy = 0;
+
+ /* X11's starting point. */
+ x = -ch->lbearing;
+ y = ch->ascent;
+
+ /* Round the width to a multiple of eight. We will use this also
+ for the pixmap for capturing the X11 font. This is slightly
+ inefficient, but it makes the OpenGL part real easy. */
+ bm_width = (width + 7) / 8;
+ bm_height = height;
+
+ glNewList(list, GL_COMPILE);
+ if (valid && (bm_width > 0) && (bm_height > 0)) {
+ crMemset(bm, '\0', bm_width * bm_height);
+ fill_bitmap(dpy, win, gc, bm_width, bm_height, x, y, c, bm);
+ glBitmap(width, height, x0, y0, dx, dy, bm);
+ }
+ else {
+ glBitmap(0, 0, 0.0, 0.0, dx, dy, NULL);
+ }
+ glEndList();
+ }
+
+ crFree(bm);
+ XFreeFontInfo(NULL, fs, 1);
+ XFreeGC(dpy, gc);
+
+ /* Restore saved packing modes. */
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, swapbytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, lsbfirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, rowlength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, skiprows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, skippixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
+}