syphon.utils.raw

 1import ctypes
 2from typing import Any, Optional
 3
 4import Metal
 5
 6
 7def create_mtl_texture(device: Any,
 8                       width: int,
 9                       height: int,
10                       pixel_format: int = Metal.MTLPixelFormatRGBA8Unorm) -> Any:
11    """
12    Create a Metal texture with the specified parameters.
13
14    Parameters:
15    - device (Any): The Metal device.
16    - width (int): The width of the texture.
17    - height (int): The height of the texture.
18    - pixel_format (int): The pixel format of the texture (default: MTLPixelFormatRGBA8Unorm).
19
20    Returns:
21    - Any: The created Metal texture.
22    """
23    texture_descriptor = Metal.MTLTextureDescriptor.texture2DDescriptorWithPixelFormat_width_height_mipmapped_(
24        pixel_format, width, height, False
25    )
26
27    return device.newTextureWithDescriptor_(texture_descriptor)
28
29
30def copy_bytes_to_mtl_texture(data: bytes, texture: Any):
31    """
32    Copy pixel data from a bytes object to a Metal texture.
33
34    Parameters:
35    - data (bytes): The pixel data as bytes.
36    - texture (Any): The target Metal texture to copy the pixel data into.
37    """
38    region = Metal.MTLRegion((0, 0, 0), (texture.width(), texture.height(), 1))
39    bytes_per_row = texture.width() * 4
40
41    texture.replaceRegion_mipmapLevel_withBytes_bytesPerRow_(
42        region,
43        0,  # mipmapLevel
44        data,
45        bytes_per_row
46    )
47
48
49def copy_mtl_texture_to_bytes(texture: Any, buffer: Optional[Any] = None) -> bytes:
50    """
51    Copy pixel data from a Metal texture to a bytes object.
52
53    Parameters:
54    - texture (Any): The source Metal texture to copy pixel data from.
55    - buffer (Optional[Any]): The buffer to store the result. If None, a new buffer will be created.
56
57    Returns:
58    - bytes: The resulting pixel data as bytes.
59
60    Raises:
61    - Exception: If the pixel format of the texture is not MTLPixelFormatBGRA8Unorm or MTLPixelFormatRGBA8Unorm.
62    - Exception: If the provided buffer is not big enough.
63    """
64    if (texture.pixelFormat() != Metal.MTLPixelFormatBGRA8Unorm
65            and texture.pixelFormat() != Metal.MTLPixelFormatRGBA8Unorm):
66        raise Exception("Not correct pixel format (expected MTLPixelFormatBGRA8Unorm or MTLPixelFormatRGBA8Unorm)")
67
68    bytes_per_row = texture.width() * 4
69    bytes_per_image = bytes_per_row * texture.height()
70    mipmap_level = 0
71    slice_number = 0
72    region = Metal.MTLRegionMake2D(0, 0, texture.width(), texture.height())
73
74    if buffer is None:
75        buffer = ctypes.create_string_buffer(bytes_per_image)
76
77    if len(buffer) != bytes_per_image:
78        raise Exception(f"Buffer is not big enough (expected: {bytes_per_image}, actual: {len(buffer)})")
79
80    texture.getBytes_bytesPerRow_bytesPerImage_fromRegion_mipmapLevel_slice_(buffer,
81                                                                             bytes_per_row,
82                                                                             bytes_per_image,
83                                                                             region,
84                                                                             mipmap_level,
85                                                                             slice_number)
86
87    raw_bytes = bytes(buffer.raw)
88    return raw_bytes
def create_mtl_texture(device: Any, width: int, height: int, pixel_format: int = 70) -> Any:
 8def create_mtl_texture(device: Any,
 9                       width: int,
10                       height: int,
11                       pixel_format: int = Metal.MTLPixelFormatRGBA8Unorm) -> Any:
12    """
13    Create a Metal texture with the specified parameters.
14
15    Parameters:
16    - device (Any): The Metal device.
17    - width (int): The width of the texture.
18    - height (int): The height of the texture.
19    - pixel_format (int): The pixel format of the texture (default: MTLPixelFormatRGBA8Unorm).
20
21    Returns:
22    - Any: The created Metal texture.
23    """
24    texture_descriptor = Metal.MTLTextureDescriptor.texture2DDescriptorWithPixelFormat_width_height_mipmapped_(
25        pixel_format, width, height, False
26    )
27
28    return device.newTextureWithDescriptor_(texture_descriptor)

Create a Metal texture with the specified parameters.

Parameters:

  • device (Any): The Metal device.
  • width (int): The width of the texture.
  • height (int): The height of the texture.
  • pixel_format (int): The pixel format of the texture (default: MTLPixelFormatRGBA8Unorm).

Returns:

  • Any: The created Metal texture.
def copy_bytes_to_mtl_texture(data: bytes, texture: Any):
31def copy_bytes_to_mtl_texture(data: bytes, texture: Any):
32    """
33    Copy pixel data from a bytes object to a Metal texture.
34
35    Parameters:
36    - data (bytes): The pixel data as bytes.
37    - texture (Any): The target Metal texture to copy the pixel data into.
38    """
39    region = Metal.MTLRegion((0, 0, 0), (texture.width(), texture.height(), 1))
40    bytes_per_row = texture.width() * 4
41
42    texture.replaceRegion_mipmapLevel_withBytes_bytesPerRow_(
43        region,
44        0,  # mipmapLevel
45        data,
46        bytes_per_row
47    )

Copy pixel data from a bytes object to a Metal texture.

Parameters:

  • data (bytes): The pixel data as bytes.
  • texture (Any): The target Metal texture to copy the pixel data into.
def copy_mtl_texture_to_bytes(texture: Any, buffer: Optional[Any] = None) -> bytes:
50def copy_mtl_texture_to_bytes(texture: Any, buffer: Optional[Any] = None) -> bytes:
51    """
52    Copy pixel data from a Metal texture to a bytes object.
53
54    Parameters:
55    - texture (Any): The source Metal texture to copy pixel data from.
56    - buffer (Optional[Any]): The buffer to store the result. If None, a new buffer will be created.
57
58    Returns:
59    - bytes: The resulting pixel data as bytes.
60
61    Raises:
62    - Exception: If the pixel format of the texture is not MTLPixelFormatBGRA8Unorm or MTLPixelFormatRGBA8Unorm.
63    - Exception: If the provided buffer is not big enough.
64    """
65    if (texture.pixelFormat() != Metal.MTLPixelFormatBGRA8Unorm
66            and texture.pixelFormat() != Metal.MTLPixelFormatRGBA8Unorm):
67        raise Exception("Not correct pixel format (expected MTLPixelFormatBGRA8Unorm or MTLPixelFormatRGBA8Unorm)")
68
69    bytes_per_row = texture.width() * 4
70    bytes_per_image = bytes_per_row * texture.height()
71    mipmap_level = 0
72    slice_number = 0
73    region = Metal.MTLRegionMake2D(0, 0, texture.width(), texture.height())
74
75    if buffer is None:
76        buffer = ctypes.create_string_buffer(bytes_per_image)
77
78    if len(buffer) != bytes_per_image:
79        raise Exception(f"Buffer is not big enough (expected: {bytes_per_image}, actual: {len(buffer)})")
80
81    texture.getBytes_bytesPerRow_bytesPerImage_fromRegion_mipmapLevel_slice_(buffer,
82                                                                             bytes_per_row,
83                                                                             bytes_per_image,
84                                                                             region,
85                                                                             mipmap_level,
86                                                                             slice_number)
87
88    raw_bytes = bytes(buffer.raw)
89    return raw_bytes

Copy pixel data from a Metal texture to a bytes object.

Parameters:

  • texture (Any): The source Metal texture to copy pixel data from.
  • buffer (Optional[Any]): The buffer to store the result. If None, a new buffer will be created.

Returns:

  • bytes: The resulting pixel data as bytes.

Raises:

  • Exception: If the pixel format of the texture is not MTLPixelFormatBGRA8Unorm or MTLPixelFormatRGBA8Unorm.
  • Exception: If the provided buffer is not big enough.