Implementation:Google deepmind Dm control Render Context Base
| Knowledge Sources | |
|---|---|
| Domains | Rendering, OpenGL |
| Last Updated | 2026-02-15 04:00 GMT |
Overview
ContextBase is the abstract base class that all OpenGL rendering context implementations (GLFW, EGL, OSMesa) must inherit from, providing a common API for context lifecycle management and thread-safe rendering.
Description
ContextBase uses a RenderExecutor to ensure OpenGL calls happen on the correct thread. It tracks which context is current on which thread via module-level dictionaries (_CURRENT_CONTEXT_FOR_THREAD and _CURRENT_THREAD_FOR_CONTEXT) and provides a make_current() context manager that activates the OpenGL context and yields an execution proxy for thread-safe calls.
Lifecycle management includes reference counting via increment_refcount/decrement_refcount, a keep_alive mechanism for preventing premature garbage collection of dependent objects (such as MuJoCo scene resources), and atexit cleanup via weak references. When the context is freed, it makes itself current on the executor thread, frees all "patient" objects, and then calls the platform-specific cleanup.
Subclasses implement three abstract methods: _platform_init, _platform_make_current, and _platform_free. This pattern enforces a consistent interface across all OpenGL backends while encapsulating the complex thread-safety and resource management logic that would otherwise need to be duplicated in each backend implementation.
Usage
Use this class as the base for any new OpenGL rendering backend. Application code does not instantiate ContextBase directly but instead uses one of the concrete subclasses (GLFWContext, EGLContext, OSMesaContext). The make_current() context manager is the primary entry point for performing OpenGL rendering operations.
Code Reference
Source Location
- Repository: Google_deepmind_Dm_control
- File: dm_control/_render/base.py
- Lines: 1-166
Signature
class ContextBase(metaclass=abc.ABCMeta):
def __init__(self, max_width, max_height,
render_executor_class=executor.RenderExecutor):
def keep_alive(self, obj):
def dont_keep_alive(self, obj):
def increment_refcount(self):
def decrement_refcount(self):
@property
def terminated(self):
@property
def thread(self):
def free(self):
@contextlib.contextmanager
def make_current(self):
def to_pixels(self, buffer):
@abc.abstractmethod
def _platform_init(self, max_width, max_height):
@abc.abstractmethod
def _platform_make_current(self):
@abc.abstractmethod
def _platform_free(self):
Import
from dm_control._render.base import ContextBase
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| max_width | int | Yes | Maximum framebuffer width in pixels |
| max_height | int | Yes | Maximum framebuffer height in pixels |
| render_executor_class | class | No | The RenderExecutor class to use for thread management (defaults to executor.RenderExecutor)
|
Outputs
| Name | Type | Description |
|---|---|---|
| make_current() | context manager | Yields an execution context proxy with a call method for thread-safe OpenGL calls
|
| to_pixels(buffer) | numpy.ndarray | Flipped (vertically) pixel array from the given buffer |
| terminated | bool | Whether the render executor has been terminated |
| thread | threading.Thread | The thread associated with this context's render executor |
Usage Examples
# Using a concrete subclass with the make_current() context manager
from dm_control._render.glfw_renderer import GLFWContext
context = GLFWContext(max_width=640, max_height=480)
with context.make_current() as ctx:
# Execute OpenGL calls on the correct thread
ctx.call(some_opengl_function, arg1, arg2)
result = ctx.call(another_opengl_function)
# Prevent premature garbage collection of a dependent object
context.keep_alive(some_mujoco_resource)
# Free the context when done
context.free()