PyOpenGL-accelerate 4.0.0a1__tar.gz → 4.0.0a4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyopengl_accelerate-4.0.0a1 → pyopengl_accelerate-4.0.0a4}/OpenGL_accelerate/__init__.py +1 -1
- {pyopengl_accelerate-4.0.0a1 → pyopengl_accelerate-4.0.0a4}/PKG-INFO +3 -1
- {pyopengl_accelerate-4.0.0a1 → pyopengl_accelerate-4.0.0a4}/PyOpenGL_accelerate.egg-info/PKG-INFO +3 -1
- {pyopengl_accelerate-4.0.0a1 → pyopengl_accelerate-4.0.0a4}/PyOpenGL_accelerate.egg-info/SOURCES.txt +13 -0
- pyopengl_accelerate-4.0.0a4/PyOpenGL_accelerate.egg-info/requires.txt +1 -0
- {pyopengl_accelerate-4.0.0a1 → pyopengl_accelerate-4.0.0a4}/pyproject.toml +18 -1
- pyopengl_accelerate-4.0.0a4/setup.py +224 -0
- {pyopengl_accelerate-4.0.0a1 → pyopengl_accelerate-4.0.0a4}/src/arraydatatype.pyx +83 -1
- pyopengl_accelerate-4.0.0a4/src/c/generated/pygl_EGL.c +6283 -0
- pyopengl_accelerate-4.0.0a4/src/c/generated/pygl_GL.c +120234 -0
- pyopengl_accelerate-4.0.0a4/src/c/generated/pygl_GLES1.c +15983 -0
- pyopengl_accelerate-4.0.0a4/src/c/generated/pygl_GLES2.c +29952 -0
- pyopengl_accelerate-4.0.0a4/src/c/generated/pygl_GLES3.c +7004 -0
- pyopengl_accelerate-4.0.0a4/src/c/generated/pygl_GLSC2.c +4350 -0
- pyopengl_accelerate-4.0.0a4/src/c/generated/pygl_GLX.c +5068 -0
- pyopengl_accelerate-4.0.0a4/src/c/generated/pygl_WGL.c +5736 -0
- pyopengl_accelerate-4.0.0a4/src/c/generated/pygl_generated.c +44 -0
- pyopengl_accelerate-4.0.0a4/src/c/generated/pygl_modules.c +23632 -0
- pyopengl_accelerate-4.0.0a4/src/c/pygl_handwritten.c +119 -0
- pyopengl_accelerate-4.0.0a4/src/c/pygl_runtime.c +2966 -0
- {pyopengl_accelerate-4.0.0a1 → pyopengl_accelerate-4.0.0a4}/src/errorchecker.pyx +52 -9
- {pyopengl_accelerate-4.0.0a1 → pyopengl_accelerate-4.0.0a4}/src/wrapper.pyx +11 -0
- {pyopengl_accelerate-4.0.0a1 → pyopengl_accelerate-4.0.0a4}/tests/test_arraydatatypeaccel.py +19 -4
- {pyopengl_accelerate-4.0.0a1 → pyopengl_accelerate-4.0.0a4}/tests/test_numpyaccel.py +21 -2
- pyopengl_accelerate-4.0.0a1/setup.py +0 -121
- {pyopengl_accelerate-4.0.0a1 → pyopengl_accelerate-4.0.0a4}/MANIFEST.in +0 -0
- {pyopengl_accelerate-4.0.0a1 → pyopengl_accelerate-4.0.0a4}/OpenGL_accelerate/formathandler.pxd +0 -0
- {pyopengl_accelerate-4.0.0a1 → pyopengl_accelerate-4.0.0a4}/OpenGL_accelerate/wrapper.pxd +0 -0
- {pyopengl_accelerate-4.0.0a1 → pyopengl_accelerate-4.0.0a4}/PyOpenGL_accelerate.egg-info/dependency_links.txt +0 -0
- {pyopengl_accelerate-4.0.0a1 → pyopengl_accelerate-4.0.0a4}/PyOpenGL_accelerate.egg-info/top_level.txt +0 -0
- {pyopengl_accelerate-4.0.0a1 → pyopengl_accelerate-4.0.0a4}/README.md +0 -0
- {pyopengl_accelerate-4.0.0a1 → pyopengl_accelerate-4.0.0a4}/license.txt +0 -0
- {pyopengl_accelerate-4.0.0a1 → pyopengl_accelerate-4.0.0a4}/setup.cfg +0 -0
- {pyopengl_accelerate-4.0.0a1 → pyopengl_accelerate-4.0.0a4}/src/buffers_formathandler.pyx +0 -0
- {pyopengl_accelerate-4.0.0a1 → pyopengl_accelerate-4.0.0a4}/src/formathandler.pyx +0 -0
- {pyopengl_accelerate-4.0.0a1 → pyopengl_accelerate-4.0.0a4}/src/latebind.pyx +0 -0
- {pyopengl_accelerate-4.0.0a1 → pyopengl_accelerate-4.0.0a4}/src/nones_formathandler.pyx +0 -0
- {pyopengl_accelerate-4.0.0a1 → pyopengl_accelerate-4.0.0a4}/src/numpy_formathandler.pyx +0 -0
- {pyopengl_accelerate-4.0.0a1 → pyopengl_accelerate-4.0.0a4}/src/vbo.pyx +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyOpenGL-accelerate
|
|
3
|
-
Version: 4.0.
|
|
3
|
+
Version: 4.0.0a4
|
|
4
4
|
Summary: Cython-coded accelerators for PyOpenGL
|
|
5
5
|
Home-page: http://pyopengl.sourceforge.net
|
|
6
6
|
Download-URL: http://sourceforge.net/project/showfiles.php?group_id=5988
|
|
@@ -24,8 +24,10 @@ Classifier: Intended Audience :: Developers
|
|
|
24
24
|
Requires-Python: >=3.9
|
|
25
25
|
Description-Content-Type: text/markdown
|
|
26
26
|
License-File: license.txt
|
|
27
|
+
Requires-Dist: PyOpenGL==4.0.0a4
|
|
27
28
|
Dynamic: download-url
|
|
28
29
|
Dynamic: license-file
|
|
30
|
+
Dynamic: requires-dist
|
|
29
31
|
|
|
30
32
|
# Acceleration code for PyOpenGL
|
|
31
33
|
|
{pyopengl_accelerate-4.0.0a1 → pyopengl_accelerate-4.0.0a4}/PyOpenGL_accelerate.egg-info/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: PyOpenGL-accelerate
|
|
3
|
-
Version: 4.0.
|
|
3
|
+
Version: 4.0.0a4
|
|
4
4
|
Summary: Cython-coded accelerators for PyOpenGL
|
|
5
5
|
Home-page: http://pyopengl.sourceforge.net
|
|
6
6
|
Download-URL: http://sourceforge.net/project/showfiles.php?group_id=5988
|
|
@@ -24,8 +24,10 @@ Classifier: Intended Audience :: Developers
|
|
|
24
24
|
Requires-Python: >=3.9
|
|
25
25
|
Description-Content-Type: text/markdown
|
|
26
26
|
License-File: license.txt
|
|
27
|
+
Requires-Dist: PyOpenGL==4.0.0a4
|
|
27
28
|
Dynamic: download-url
|
|
28
29
|
Dynamic: license-file
|
|
30
|
+
Dynamic: requires-dist
|
|
29
31
|
|
|
30
32
|
# Acceleration code for PyOpenGL
|
|
31
33
|
|
{pyopengl_accelerate-4.0.0a1 → pyopengl_accelerate-4.0.0a4}/PyOpenGL_accelerate.egg-info/SOURCES.txt
RENAMED
|
@@ -10,6 +10,7 @@ OpenGL_accelerate/wrapper.pxd
|
|
|
10
10
|
PyOpenGL_accelerate.egg-info/PKG-INFO
|
|
11
11
|
PyOpenGL_accelerate.egg-info/SOURCES.txt
|
|
12
12
|
PyOpenGL_accelerate.egg-info/dependency_links.txt
|
|
13
|
+
PyOpenGL_accelerate.egg-info/requires.txt
|
|
13
14
|
PyOpenGL_accelerate.egg-info/top_level.txt
|
|
14
15
|
src/arraydatatype.pyx
|
|
15
16
|
src/buffers_formathandler.pyx
|
|
@@ -20,5 +21,17 @@ src/nones_formathandler.pyx
|
|
|
20
21
|
src/numpy_formathandler.pyx
|
|
21
22
|
src/vbo.pyx
|
|
22
23
|
src/wrapper.pyx
|
|
24
|
+
src/c/pygl_handwritten.c
|
|
25
|
+
src/c/pygl_runtime.c
|
|
26
|
+
src/c/generated/pygl_EGL.c
|
|
27
|
+
src/c/generated/pygl_GL.c
|
|
28
|
+
src/c/generated/pygl_GLES1.c
|
|
29
|
+
src/c/generated/pygl_GLES2.c
|
|
30
|
+
src/c/generated/pygl_GLES3.c
|
|
31
|
+
src/c/generated/pygl_GLSC2.c
|
|
32
|
+
src/c/generated/pygl_GLX.c
|
|
33
|
+
src/c/generated/pygl_WGL.c
|
|
34
|
+
src/c/generated/pygl_generated.c
|
|
35
|
+
src/c/generated/pygl_modules.c
|
|
23
36
|
tests/test_arraydatatypeaccel.py
|
|
24
37
|
tests/test_numpyaccel.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
PyOpenGL==4.0.0a4
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name="PyOpenGL-accelerate"
|
|
3
|
-
dynamic=["version"]
|
|
3
|
+
dynamic=["version", "dependencies"]
|
|
4
4
|
description = "Cython-coded accelerators for PyOpenGL"
|
|
5
5
|
authors = [
|
|
6
6
|
{name="Mike C. Fletcher",email="mcfletch@vrplumber.com"},
|
|
@@ -47,9 +47,26 @@ build-backend = "setuptools.build_meta"
|
|
|
47
47
|
|
|
48
48
|
[tool.setuptools.dynamic]
|
|
49
49
|
version = {attr = "OpenGL_accelerate.__version__"}
|
|
50
|
+
# The dependency on PyOpenGL is an exact pin on this package's own version, so
|
|
51
|
+
# setup.py builds it from the one number rather than a second copy living here
|
|
52
|
+
# to drift -- see pyopengl_requirement().
|
|
50
53
|
|
|
51
54
|
[tool.setuptools.packages.find]
|
|
52
55
|
namespaces=false
|
|
53
56
|
include=["OpenGL_accelerate"]
|
|
54
57
|
exclude=["tests","src"]
|
|
55
58
|
|
|
59
|
+
# uv decides whether its cached metadata for a source tree is still current
|
|
60
|
+
# from pyproject.toml, setup.py and setup.cfg alone. This project's version
|
|
61
|
+
# lives in OpenGL_accelerate/__init__.py, so name that file too: without it a
|
|
62
|
+
# version bump leaves uv answering with the previous number, and a dependent
|
|
63
|
+
# requiring the new one resolves against PyPI rather than this checkout.
|
|
64
|
+
[tool.uv]
|
|
65
|
+
# setup.py too: the dependency on PyOpenGL is built there, from the version
|
|
66
|
+
# in OpenGL_accelerate/__init__.py, so both files decide this package's
|
|
67
|
+
# metadata and a change to either has to invalidate the cached answer.
|
|
68
|
+
cache-keys = [
|
|
69
|
+
{ file = "pyproject.toml" },
|
|
70
|
+
{ file = "setup.py" },
|
|
71
|
+
{ file = "OpenGL_accelerate/__init__.py" },
|
|
72
|
+
]
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Builds accelleration functions for PyOpenGL
|
|
3
|
+
"""
|
|
4
|
+
import sys
|
|
5
|
+
from setuptools import setup, Extension
|
|
6
|
+
|
|
7
|
+
try:
|
|
8
|
+
from Cython.Distutils import build_ext
|
|
9
|
+
except ImportError:
|
|
10
|
+
have_cython = False
|
|
11
|
+
build_ext = False
|
|
12
|
+
else:
|
|
13
|
+
have_cython = True
|
|
14
|
+
|
|
15
|
+
import sys, os
|
|
16
|
+
|
|
17
|
+
HERE = os.path.normpath(os.path.abspath(os.path.dirname(__file__)))
|
|
18
|
+
|
|
19
|
+
extensions = []
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _our_version():
|
|
23
|
+
"""This package's version, read without importing it.
|
|
24
|
+
|
|
25
|
+
Importing ``OpenGL_accelerate`` during its own build would need the
|
|
26
|
+
extensions that are not built yet, so the assignment is read out of the
|
|
27
|
+
source the way the build backend reads it.
|
|
28
|
+
"""
|
|
29
|
+
import re
|
|
30
|
+
|
|
31
|
+
with open(
|
|
32
|
+
os.path.join(HERE, 'OpenGL_accelerate', '__init__.py'), encoding='utf-8'
|
|
33
|
+
) as handle:
|
|
34
|
+
source = handle.read()
|
|
35
|
+
found = re.search(r'^__version__\s*=\s*["\']([^"\']+)["\']', source, re.M)
|
|
36
|
+
if not found:
|
|
37
|
+
raise RuntimeError('OpenGL_accelerate/__init__.py states no __version__')
|
|
38
|
+
return found.group(1)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def pyopengl_requirement():
|
|
42
|
+
"""The PyOpenGL this accelerate pairs with, as a requirement string.
|
|
43
|
+
|
|
44
|
+
Exact, because the two are released together from one repository and the
|
|
45
|
+
dispatch extension's tables are generated from that PyOpenGL: a mismatched
|
|
46
|
+
pair does not degrade, it dispatches through the wrong slot indices.
|
|
47
|
+
``OpenGL._dispatch`` refuses one at import; this stops pip assembling one
|
|
48
|
+
in the first place, which is a better place to learn it than the first
|
|
49
|
+
entry point a program calls.
|
|
50
|
+
|
|
51
|
+
Read from this package's own version so there is one number to bump.
|
|
52
|
+
"""
|
|
53
|
+
return 'PyOpenGL==%s' % (_our_version(),)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def dispatch_extension():
|
|
57
|
+
"""The registry-generated C implementation of the OpenGL entry points.
|
|
58
|
+
|
|
59
|
+
It lives here rather than in ``pyopengl`` so that ``pyopengl`` stays a
|
|
60
|
+
single universal wheel: the C is what needs a compiler and a wheel per
|
|
61
|
+
platform, and this package is already the optional compiled companion.
|
|
62
|
+
"Is the fast path available?" is then the question it has always been --
|
|
63
|
+
is accelerate installed?
|
|
64
|
+
|
|
65
|
+
Both packages are released together from one repository, and the two
|
|
66
|
+
share generated tables, so the versions must match exactly; the module
|
|
67
|
+
checks that at import.
|
|
68
|
+
"""
|
|
69
|
+
import glob
|
|
70
|
+
|
|
71
|
+
if os.environ.get('PYOPENGL_NO_C_DISPATCH'):
|
|
72
|
+
return []
|
|
73
|
+
if sys.implementation.name != 'cpython':
|
|
74
|
+
# The extension reaches CPython's vectorcall protocol directly. On
|
|
75
|
+
# PyPy it would compile, import, and route every call through an
|
|
76
|
+
# emulated vectorcall across the cpyext boundary -- the slowest path
|
|
77
|
+
# available, chosen by default, on the interpreter the ctypes
|
|
78
|
+
# implementation exists to serve.
|
|
79
|
+
return []
|
|
80
|
+
generated = os.path.join(HERE, 'src', 'c', 'generated')
|
|
81
|
+
sources = sorted(
|
|
82
|
+
os.path.relpath(path, HERE).replace(os.sep, '/')
|
|
83
|
+
for path in glob.glob(os.path.join(generated, '*.c'))
|
|
84
|
+
)
|
|
85
|
+
if not sources:
|
|
86
|
+
return []
|
|
87
|
+
sources.insert(0, 'src/c/pygl_handwritten.c')
|
|
88
|
+
sources.insert(0, 'src/c/pygl_runtime.c')
|
|
89
|
+
# setuptools does not work out header dependencies, so a change to pygl.h
|
|
90
|
+
# would otherwise leave the generated objects stale and the build mixed:
|
|
91
|
+
# objects compiled against one version of a macro linked with a runtime
|
|
92
|
+
# compiled against another.
|
|
93
|
+
headers = [
|
|
94
|
+
'src/c/pygl.h',
|
|
95
|
+
'src/c/generated/pygl_elements.h',
|
|
96
|
+
'src/c/generated/pygl_glgets.h',
|
|
97
|
+
]
|
|
98
|
+
return [
|
|
99
|
+
Extension(
|
|
100
|
+
'OpenGL_accelerate.dispatch',
|
|
101
|
+
sources=sources,
|
|
102
|
+
include_dirs=['src/c', 'src/c/generated'],
|
|
103
|
+
# The extension states which PyOpenGL its tables were generated
|
|
104
|
+
# from, so that a mismatched pair is refused with a sentence rather
|
|
105
|
+
# than dispatching through the wrong slot indices. The two are
|
|
106
|
+
# released together and carry the same number, so this is the
|
|
107
|
+
# accelerate version.
|
|
108
|
+
define_macros=[('PYOPENGL_VERSION', '"%s"' % (_our_version(),))],
|
|
109
|
+
depends=[
|
|
110
|
+
path for path in headers if os.path.exists(os.path.join(HERE, path))
|
|
111
|
+
],
|
|
112
|
+
# Optional so a source install without a compiler still yields a
|
|
113
|
+
# working accelerate; PyOpenGL falls back to ctypes on its own.
|
|
114
|
+
# Set PYOPENGL_REQUIRE_C_DISPATCH=1 while working on it, or a
|
|
115
|
+
# compile error is a warning and the stale object is kept.
|
|
116
|
+
optional=not os.environ.get('PYOPENGL_REQUIRE_C_DISPATCH'),
|
|
117
|
+
)
|
|
118
|
+
]
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
extensions.extend(dispatch_extension())
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def cython_extension(
|
|
125
|
+
name,
|
|
126
|
+
include_dirs=(),
|
|
127
|
+
):
|
|
128
|
+
"""Create a cython extension object"""
|
|
129
|
+
filenames = "%(name)s.c" % locals(), "%(name)s.pyx" % locals()
|
|
130
|
+
filename = filenames[bool(have_cython)]
|
|
131
|
+
return Extension(
|
|
132
|
+
"OpenGL_accelerate.%(name)s" % locals(),
|
|
133
|
+
[
|
|
134
|
+
os.path.join("src", filename),
|
|
135
|
+
],
|
|
136
|
+
include_dirs=[
|
|
137
|
+
os.path.join(HERE, "src"),
|
|
138
|
+
HERE,
|
|
139
|
+
]
|
|
140
|
+
+ list(include_dirs),
|
|
141
|
+
define_macros=[
|
|
142
|
+
('NPY_NO_DEPRECATED_API', 'NPY_1_7_API_VERSION'),
|
|
143
|
+
],
|
|
144
|
+
compiler_directives={'language_level': "3"} if have_cython else {},
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
extensions.extend(
|
|
149
|
+
[
|
|
150
|
+
cython_extension("wrapper"),
|
|
151
|
+
cython_extension("formathandler"),
|
|
152
|
+
cython_extension("arraydatatype"),
|
|
153
|
+
cython_extension("errorchecker"),
|
|
154
|
+
cython_extension("vbo"),
|
|
155
|
+
cython_extension("nones_formathandler"),
|
|
156
|
+
cython_extension("latebind"),
|
|
157
|
+
]
|
|
158
|
+
)
|
|
159
|
+
if sys.version_info[:2] >= (2, 7):
|
|
160
|
+
extensions.extend(
|
|
161
|
+
[
|
|
162
|
+
cython_extension("buffers_formathandler"),
|
|
163
|
+
]
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
try:
|
|
167
|
+
import numpy
|
|
168
|
+
except ImportError:
|
|
169
|
+
sys.stderr.write("""Unable to import numpy, skipping numpy extension building\n""")
|
|
170
|
+
else:
|
|
171
|
+
if hasattr(numpy, "get_include"):
|
|
172
|
+
includeDirectories = [
|
|
173
|
+
numpy.get_include(),
|
|
174
|
+
]
|
|
175
|
+
else:
|
|
176
|
+
includeDirectories = [
|
|
177
|
+
os.path.join(
|
|
178
|
+
os.path.dirname(numpy.__file__),
|
|
179
|
+
"core",
|
|
180
|
+
"include",
|
|
181
|
+
),
|
|
182
|
+
]
|
|
183
|
+
extensions.append(
|
|
184
|
+
cython_extension(
|
|
185
|
+
"numpy_formathandler",
|
|
186
|
+
includeDirectories,
|
|
187
|
+
)
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
if ( # Prevents running of setup during code introspection imports
|
|
191
|
+
__name__ == "__main__"
|
|
192
|
+
):
|
|
193
|
+
# Workaround for Broken apple Python build params echoed in distutils
|
|
194
|
+
# Approach taken from the PyMongo driver. OS-X Python builds were created with
|
|
195
|
+
# non-existent flag, and distutils passes those flags to the extension
|
|
196
|
+
# build, newer clangs now treat those flags as errors rather than warnings.
|
|
197
|
+
import platform, sys
|
|
198
|
+
|
|
199
|
+
if sys.platform == "darwin" and "clang" in platform.python_compiler().lower():
|
|
200
|
+
from distutils.sysconfig import get_config_vars
|
|
201
|
+
|
|
202
|
+
res = get_config_vars()
|
|
203
|
+
for key in ("CFLAGS", "PY_CFLAGS"):
|
|
204
|
+
if key in res:
|
|
205
|
+
res[key] = res[key].replace("-mno-fused-madd", "")
|
|
206
|
+
|
|
207
|
+
extraArguments = {}
|
|
208
|
+
### Now the actual set up call
|
|
209
|
+
if have_cython:
|
|
210
|
+
extraArguments["cmdclass"] = {
|
|
211
|
+
"build_ext": build_ext,
|
|
212
|
+
}
|
|
213
|
+
setup(
|
|
214
|
+
build_requires=['cython'],
|
|
215
|
+
install_requires=[pyopengl_requirement()],
|
|
216
|
+
options={
|
|
217
|
+
"sdist": {
|
|
218
|
+
"formats": ["gztar"],
|
|
219
|
+
"force_manifest": True,
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
ext_modules=extensions,
|
|
223
|
+
**extraArguments
|
|
224
|
+
)
|
|
@@ -303,6 +303,13 @@ cdef class Output(cArgConverter):
|
|
|
303
303
|
never reaches the caller's array -- the silent "returns zeroes" bug.
|
|
304
304
|
Detect the shrinking copy and raise. Correctly-typed arrays are not
|
|
305
305
|
copied, so they never trip this.
|
|
306
|
+
|
|
307
|
+
Then the other question, which the count answers: an array shorter than
|
|
308
|
+
the call will write into is a heap overrun rather than an exception, so
|
|
309
|
+
it is refused. See ``Output.checkOutputSize`` in OpenGL/converters.py,
|
|
310
|
+
which is the same check for the pure-Python converter -- this one is
|
|
311
|
+
what runs where accelerate is installed, whichever dispatch layer the
|
|
312
|
+
entry points come from.
|
|
306
313
|
"""
|
|
307
314
|
value = pyArgs[index]
|
|
308
315
|
result = self.arrayType.asArray( value )
|
|
@@ -311,7 +318,10 @@ cdef class Output(cArgConverter):
|
|
|
311
318
|
rbytes = self.arrayType.arrayByteCount( result )
|
|
312
319
|
vbytes = self.arrayType.arrayByteCount( value )
|
|
313
320
|
except Exception:
|
|
314
|
-
|
|
321
|
+
# Not measurable -- a list has no byte count of its own -- so
|
|
322
|
+
# there is no shrinking coercion to detect. The size the call
|
|
323
|
+
# will write is still checked below.
|
|
324
|
+
rbytes = vbytes = 0
|
|
315
325
|
if rbytes < vbytes:
|
|
316
326
|
raise TypeError(
|
|
317
327
|
'%s: pass-in output array was coerced to a smaller buffer '
|
|
@@ -319,8 +329,62 @@ cdef class Output(cArgConverter):
|
|
|
319
329
|
'into your array. Pass a correctly-typed array, or None to '
|
|
320
330
|
'have one allocated.' % ( self.name, rbytes, vbytes )
|
|
321
331
|
)
|
|
332
|
+
self.c_checkOutputSize( result, pyArgs )
|
|
322
333
|
return result
|
|
323
334
|
|
|
335
|
+
cdef int c_checkOutputSize( self, object array, tuple pyArgs ) except -1:
|
|
336
|
+
"""Nothing to check: a fixed declared size is a maximum.
|
|
337
|
+
|
|
338
|
+
Which of it a call fills depends on the pname -- glGetVertexAttribiv
|
|
339
|
+
declares four and writes one for most of them -- so a shorter array is
|
|
340
|
+
legitimate here. :class:`SizedOutput` overrides this, because its size
|
|
341
|
+
is a count the caller passed and so says what will be written.
|
|
342
|
+
"""
|
|
343
|
+
return 0
|
|
344
|
+
|
|
345
|
+
cdef int c_checkPromisedSize( self, object array, tuple pyArgs ) except -1:
|
|
346
|
+
"""Refuse an output array smaller than the call will write into it.
|
|
347
|
+
|
|
348
|
+
Only a shortfall: a larger array is a caller deliberately reusing one
|
|
349
|
+
buffer for several calls, which is ordinary and safe.
|
|
350
|
+
"""
|
|
351
|
+
cdef long wanted = 1
|
|
352
|
+
try:
|
|
353
|
+
shape = self.c_getSize( pyArgs )
|
|
354
|
+
except Exception:
|
|
355
|
+
return 0
|
|
356
|
+
if shape is None:
|
|
357
|
+
return 0
|
|
358
|
+
for dimension in shape:
|
|
359
|
+
try:
|
|
360
|
+
wanted = wanted * int(dimension)
|
|
361
|
+
except (TypeError, ValueError):
|
|
362
|
+
return 0
|
|
363
|
+
if wanted <= 0:
|
|
364
|
+
return 0
|
|
365
|
+
# Compared in bytes, not elements. The count is in units of the type
|
|
366
|
+
# the *declaration* names -- glGetBufferSubData's `size` is a byte
|
|
367
|
+
# count, glGenTextures' `n` is a count of GLuint -- and the caller may
|
|
368
|
+
# pass an array of some other type holding the same bytes.
|
|
369
|
+
# Only what carries its own length. A bare ctypes pointer does not --
|
|
370
|
+
# the hand-written wrappers in OpenGL/GL/exceptional.py pass
|
|
371
|
+
# `typedPointer` results straight down -- and arrayByteCount answers
|
|
372
|
+
# for one anyway, with the size of a single element.
|
|
373
|
+
if not hasattr( array, '__len__' ):
|
|
374
|
+
return 0
|
|
375
|
+
try:
|
|
376
|
+
wanted_bytes = wanted * ctypes.sizeof( self.arrayType.baseType )
|
|
377
|
+
held_bytes = self.arrayType.arrayByteCount( array )
|
|
378
|
+
except Exception:
|
|
379
|
+
return 0
|
|
380
|
+
if held_bytes < wanted_bytes:
|
|
381
|
+
raise ValueError(
|
|
382
|
+
'%s: output array holds %d byte(s), but the call will '
|
|
383
|
+
'write %d. Pass a larger array, or None to have one '
|
|
384
|
+
'allocated.' % ( self.name, held_bytes, wanted_bytes )
|
|
385
|
+
)
|
|
386
|
+
return 0
|
|
387
|
+
|
|
324
388
|
def oldStyleReturn( self, object result, object baseOperation, tuple pyArgs, tuple cArgs ):
|
|
325
389
|
"""Retrieve cArgs[ self.index ]"""
|
|
326
390
|
#TODO: make this a c_api-bearing value, not a Python function call
|
|
@@ -362,6 +426,24 @@ cdef class SizedOutput( Output ):
|
|
|
362
426
|
def finalise( self, wrapper ):
|
|
363
427
|
super( SizedOutput,self).finalise( wrapper )
|
|
364
428
|
self.index = wrapper.pyArgIndex( self.specifier )
|
|
429
|
+
cdef int c_checkOutputSize( self, object array, tuple pyArgs ) except -1:
|
|
430
|
+
"""Check the size only where it says what this call will write.
|
|
431
|
+
|
|
432
|
+
It does when it comes from a *count* the caller passed --
|
|
433
|
+
glGenTextures(n, names) writes n, glGetBufferSubData writes `size`
|
|
434
|
+
bytes -- which the declaration spells `size=lambda x: (x,)`.
|
|
435
|
+
|
|
436
|
+
It does not when it comes from a table keyed on a *pname*, which says
|
|
437
|
+
how large that piece of state is in total; how much of it a call fills
|
|
438
|
+
is the call's business, and glGetIntegeri_v writes one element of a
|
|
439
|
+
three-element pname at a time. The declaration spells that
|
|
440
|
+
`size=<a dict>`, handed on as its `__getitem__` -- so the dict it is
|
|
441
|
+
bound to is what tells the two apart.
|
|
442
|
+
"""
|
|
443
|
+
if isinstance( getattr( self.lookup, '__self__', None ), dict ):
|
|
444
|
+
return 0
|
|
445
|
+
return self.c_checkPromisedSize( array, pyArgs )
|
|
446
|
+
|
|
365
447
|
cdef tuple c_getSize( self, tuple pyArgs ):
|
|
366
448
|
"""Retrieve the array size for this argument"""
|
|
367
449
|
try:
|