# This file was generated by stubgen-pyx v0.2.6 from cuda_core/cuda/core/_graphics.pyx

from __future__ import annotations

from typing import Sequence

from cuda.bindings import cydriver
from cuda.core._memory._buffer import Buffer
from cuda.core._stream import Stream


class GraphicsResource:
    """RAII wrapper for a CUDA graphics resource (``CUgraphicsResource``).

    A :class:`GraphicsResource` represents an OpenGL buffer or image that has
    been registered for access by CUDA. This enables zero-copy sharing of GPU
    data between CUDA compute kernels and graphics renderers.

    Mapping the resource returns a :class:`~cuda.core.Buffer` whose lifetime
    controls when the graphics resource is unmapped. This keeps stream-ordered
    cleanup tied to the mapped pointer itself rather than to mutable state on
    the :class:`GraphicsResource` object.

    The resource is automatically unregistered when :meth:`close` is called or
    when the object is garbage collected.

    :class:`GraphicsResource` objects should not be instantiated directly.
    Use the factory classmethods :meth:`from_gl_buffer` or :meth:`from_gl_image`.

    Examples
    --------
    Register an OpenGL VBO, map it to get a buffer, and write to it from CUDA:

    .. code-block:: python

        resource = GraphicsResource.from_gl_buffer(vbo)

        with resource.map(stream=s) as buf:
            view = StridedMemoryView.from_buffer(buf, shape=(256,), dtype=np.float32)
            # view.ptr is a CUDA device pointer into the GL buffer

    Or scope registration separately from mapping:

    .. code-block:: python

        with GraphicsResource.from_gl_buffer(vbo) as resource:
            with resource.map(stream=s) as buf:
                # ... launch kernels using buf.handle, buf.size ...
                pass
    """

    def close(self, stream: object=None):
        """Unregister this graphics resource from CUDA.

        If the resource is currently mapped, it is unmapped first. After
        closing, the resource cannot be used again.

        Parameters
        ----------
        stream : :class:`~cuda.core.Stream`, optional
            Optional override for the stream used to close the currently
            mapped buffer, if one exists.
        """

    def __init__(self) -> None:
        ...

    @classmethod
    def from_gl_buffer(cls, gl_buffer: int, *, flags: str | tuple[str, ...] | list[str] | None=None, stream: Stream | None=None) -> GraphicsResource:
        """Register an OpenGL buffer object for CUDA access.

        Parameters
        ----------
        gl_buffer : int
            The OpenGL buffer name (``GLuint``) to register.
        flags : str or sequence of str, optional
            Registration flags specifying intended usage. Accepted values:
            ``"none"``, ``"read_only"``, ``"write_discard"``,
            ``"surface_load_store"``, ``"texture_gather"``.
            Multiple flags can be combined by passing a sequence
            (e.g., ``("surface_load_store", "read_only")``).
            Defaults to ``None`` (no flags).
        stream : :class:`~cuda.core.Stream`, optional
            If provided, the resource can be used directly as a context manager
            and it will be mapped on entry::

                with GraphicsResource.from_gl_buffer(vbo, stream=s) as buf:
                    view = StridedMemoryView.from_buffer(buf, shape=(256,), dtype=np.float32)

            If omitted, the returned resource can still be used as a context
            manager to scope registration and automatic cleanup::

                with GraphicsResource.from_gl_buffer(vbo) as resource:
                    with resource.map(stream=s) as buf:
                        ...

        Returns
        -------
        GraphicsResource
            A new graphics resource wrapping the registered GL buffer.
            The returned resource can be used as a context manager. If
            *stream* was given, entering maps the resource and yields a
            :class:`~cuda.core.Buffer`; otherwise entering yields the
            :class:`GraphicsResource` itself and closes it on exit.

        Raises
        ------
        CUDAError
            If the registration fails (e.g., no current GL context, invalid
            buffer name, or operating system error).
        ValueError
            If an unknown flag string is provided.
        """

    @classmethod
    def from_gl_image(cls, image: int, target: int, *, flags: str | tuple[str, ...] | list[str] | None=None) -> GraphicsResource:
        """Register an OpenGL texture or renderbuffer for CUDA access.

        Parameters
        ----------
        image : int
            The OpenGL texture or renderbuffer name (``GLuint``) to register.
        target : int
            The OpenGL target type (e.g., ``GL_TEXTURE_2D``).
        flags : str or sequence of str, optional
            Registration flags specifying intended usage. Accepted values:
            ``"none"``, ``"read_only"``, ``"write_discard"``,
            ``"surface_load_store"``, ``"texture_gather"``.
            Multiple flags can be combined by passing a sequence
            (e.g., ``("surface_load_store", "read_only")``).
            Defaults to ``None`` (no flags).

        Returns
        -------
        GraphicsResource
            A new graphics resource wrapping the registered GL image.

        Raises
        ------
        CUDAError
            If the registration fails.
        ValueError
            If an unknown flag string is provided.
        """

    def _get_mapped_buffer(self) -> object:
        ...

    def map(self, *, stream: Stream) -> Buffer:
        """Map this graphics resource for CUDA access.

        After mapping, a CUDA device pointer into the underlying graphics
        memory is available as a :class:`~cuda.core.Buffer`.

        Can be used as a context manager for automatic unmapping::

            with resource.map(stream=s) as buf:
                # use buf.handle, buf.size, etc.
            # automatically unmapped here

        Parameters
        ----------
        stream : :class:`~cuda.core.Stream`
            Keyword-only. The CUDA stream on which to perform the mapping.
            Must be passed explicitly; pass ``device.default_stream`` to use
            the default stream.

        Returns
        -------
        Buffer
            A buffer whose lifetime controls when the graphics resource is
            unmapped.

        Raises
        ------
        RuntimeError
            If the resource is already mapped or has been closed.
        CUDAError
            If the mapping fails.
        """

    def unmap(self, *, stream: Stream | None=None) -> None:
        """Unmap this graphics resource, releasing it back to the graphics API.

        After unmapping, the :class:`~cuda.core.Buffer` previously returned
        by :meth:`map` must not be used.

        Parameters
        ----------
        stream : :class:`~cuda.core.Stream`, optional
            If provided, overrides the stream that will be used when the
            mapped buffer is closed. Otherwise the mapping stream is reused.

        Raises
        ------
        RuntimeError
            If the resource is not currently mapped or has been closed.
        CUDAError
            If the unmapping fails.
        """

    def __enter__(self) -> object:
        ...

    def __exit__(self, exc_type: type | None, exc_val: BaseException | None, exc_tb: object) -> bool:
        ...

    @property
    def is_mapped(self) -> bool:
        """Whether the resource is currently mapped for CUDA access."""

    @property
    def handle(self) -> int:
        """The raw ``CUgraphicsResource`` handle as a Python int."""

    @property
    def resource_handle(self) -> int:
        """Alias for :attr:`handle`."""

    def __repr__(self) -> str:
        ...
__all__ = ['GraphicsResource']
_REGISTER_FLAGS = {'none': cydriver.CU_GRAPHICS_REGISTER_FLAGS_NONE, 'read_only': cydriver.CU_GRAPHICS_REGISTER_FLAGS_READ_ONLY, 'write_discard': cydriver.CU_GRAPHICS_REGISTER_FLAGS_WRITE_DISCARD, 'surface_load_store': cydriver.CU_GRAPHICS_REGISTER_FLAGS_SURFACE_LDST, 'texture_gather': cydriver.CU_GRAPHICS_REGISTER_FLAGS_TEXTURE_GATHER}

def _parse_register_flags(flags: str | Sequence[str] | None) -> int:
    ...