# Copyright 2017-2018 The dm_control Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================ """OpenGL context management for rendering MuJoCo scenes. By default, the `Renderer` class will try to load one of the following rendering APIs, in descending order of priority: GLFW > EGL > OSMesa. It is also possible to select a specific backend by setting the `MUJOCO_GL=` environment variable to 'glfw', 'egl', or 'osmesa'. """ import collections import os from absl import logging from dm_control._render import constants BACKEND = os.environ.get(constants.MUJOCO_GL) # pylint: disable=g-import-not-at-top def _import_egl(): from dm_control._render.pyopengl.egl_renderer import EGLContext return EGLContext def _import_glfw(): from dm_control._render.glfw_renderer import GLFWContext return GLFWContext def _import_osmesa(): from dm_control._render.pyopengl.osmesa_renderer import OSMesaContext return OSMesaContext # Import removed. # pylint: enable=g-import-not-at-top def _no_renderer(): def no_renderer(*args, **kwargs): del args, kwargs raise RuntimeError('No OpenGL rendering backend is available.') return no_renderer _ALL_RENDERERS = ( (constants.GLFW, _import_glfw), (constants.EGL, _import_egl), (constants.OSMESA, _import_osmesa), # Option removed. ) _NO_RENDERER = ( (constants.NO_RENDERER, _no_renderer), ) if BACKEND is not None: # If a backend was specified, try importing it and error if unsuccessful. import_func = None for names, importer in _ALL_RENDERERS + _NO_RENDERER: if BACKEND in names: import_func = importer BACKEND = names[0] # canonicalize the renderer name break if import_func is None: all_names = set() for names, _ in _ALL_RENDERERS + _NO_RENDERER: all_names.update(names) raise RuntimeError( 'Environment variable {} must be one of {!r}: got {!r}.' .format(constants.MUJOCO_GL, sorted(all_names), BACKEND)) logging.info('MUJOCO_GL=%s, attempting to import specified OpenGL backend.', BACKEND) Renderer = import_func() else: logging.info('MUJOCO_GL is not set, so an OpenGL backend will be chosen ' 'automatically.') # Otherwise try importing them in descending order of priority until # successful. for names, import_func in _ALL_RENDERERS: try: Renderer = import_func() BACKEND = names[0] logging.info('Successfully imported OpenGL backend: %s', names[0]) break except ImportError: logging.info('Failed to import OpenGL backend: %s', names[0]) if BACKEND is None: logging.info('No OpenGL backend could be imported. Attempting to create a ' 'rendering context will result in a RuntimeError.') Renderer = _no_renderer() USING_GPU = BACKEND in constants.EGL + constants.GLFW