File: osmesa.py

package info (click to toggle)
python-vispy 0.6.6-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 21,240 kB
  • sloc: python: 57,407; javascript: 6,810; makefile: 63; sh: 5
file content (105 lines) | stat: -rw-r--r-- 3,407 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# -*- coding: utf-8 -*-
# vispy: testskip
# Copyright (c) Vispy Development Team. All Rights Reserved.
# Distributed under the (new) BSD License. See LICENSE.txt for more info.

"""A ctypes-based API to OSMesa
"""
from __future__ import print_function
import os
import ctypes
import ctypes.util
from ctypes import c_int as _c_int, c_uint as _c_uint, c_void_p

# See vispy/gloo/gl/_constants.py for reference
GL_RGBA = 6408
GL_UNSIGNED_BYTE = 5121
GL_VERSION = 7938

_osmesa_file = None
if 'OSMESA_LIBRARY' in os.environ:
    if os.path.exists(os.environ['OSMESA_LIBRARY']):
        _osmesa_file = os.path.realpath(os.environ['OSMESA_LIBRARY'])

# Else, try to find it
if _osmesa_file is None:
    _osmesa_file = ctypes.util.find_library('OSMesa')

# Else, we failed and exit
if _osmesa_file is None:
    raise OSError('OSMesa library not found')

# Load it
_lib = ctypes.CDLL(_osmesa_file)

# Constants
OSMESA_RGBA = GL_RGBA

# Functions

# GLAPI OSMesaContext GLAPIENTRY
# OSMesaCreateContext( GLenum format, OSMesaContext sharelist );
_lib.OSMesaCreateContext.argtypes = _c_int, c_void_p
_lib.OSMesaCreateContext.restype = c_void_p
# GLAPI void GLAPIENTRY
# OSMesaDestroyContext( OSMesaContext ctx );
_lib.OSMesaDestroyContext.argtypes = c_void_p,
# GLAPI GLboolean GLAPIENTRY
# OSMesaMakeCurrent( OSMesaContext ctx, void *buffer, GLenum type,
#                   GLsizei width, GLsizei height );
_lib.OSMesaMakeCurrent.argtypes = c_void_p, c_void_p, _c_int, _c_int, _c_int
_lib.OSMesaMakeCurrent.restype = _c_int
# GLAPI OSMesaContext GLAPIENTRY
# OSMesaGetCurrentContext( void );
_lib.OSMesaGetCurrentContext.restype = c_void_p


def allocate_pixels_buffer(width, height):
    """Helper function to allocate a buffer to contain an image of
    width * height suitable for OSMesaMakeCurrent"""
    # Seems like OSMesa has some trouble with non-RGBA buffers, so enforce
    # RGBA
    return (_c_uint * width * height * 4)()


def OSMesaCreateContext():
    return ctypes.cast(_lib.OSMesaCreateContext(OSMESA_RGBA, None), c_void_p)


def OSMesaDestroyContext(context):
    _lib.OSMesaDestroyContext(context)


def OSMesaMakeCurrent(context, buffer, width, height):
    ret = _lib.OSMesaMakeCurrent(context, buffer, GL_UNSIGNED_BYTE,
                                 width, height)
    return ret != 0


def OSMesaGetCurrentContext():
    return c_void_p(_lib.OSMesaGetCurrentContext())

if __name__ == '__main__':
    """This test basic OSMesa functionality"""
    # If you have OSMesa installed alongside normal OpenGL, execute with
    # VISPY_GL_LIB=/opt/osmesa_llvmpipe/lib/libGLESv2.so \
    #   LD_LIBRARY_PATH=/opt/osmesa_llvmpipe/lib/ \
    #   OSMESA_LIBRARY=/opt/osmesa_llvmpipe/lib/libOSMesa.so \
    #   python vispy/ext/osmesa.py
    context = OSMesaCreateContext()
    w, h = 640, 480
    pixels = allocate_pixels_buffer(w, h)
    ok = OSMesaMakeCurrent(context, pixels, 640, 480)
    if not ok:
        raise RuntimeError('Failed OSMesaMakeCurrent')
    if not (OSMesaGetCurrentContext().value == context.value):
        raise RuntimeError('OSMesa context not correctly attached')

    _lib.glGetString.argtypes = (ctypes.c_uint,)
    _lib.glGetString.restype = ctypes.c_char_p

    print("OpenGL version : ", _lib.glGetString(GL_VERSION))

    OSMesaDestroyContext(context)
    if OSMesaGetCurrentContext().value is not None:
        raise RuntimeError('Failed to destroy OSMesa context')