feat: 新增 42 个 Android API 模块
新增模块覆盖: 系统层 (14): system, security, print, opengl, renderscript, transition, test, service_notification, service_controls, service_quicksettings, service_wallpaper, service_autofill, service_dreams, service_vr 应用层 (13): app_admin, app_backup, app_job, app_usage, app_role, app_people, appwidget, companion, credentials, mtp, sip, telecom, speech 硬件媒体层 (15): hardware_display, hardware_fingerprint, hardware_usb, hardware_input, media_audiofx, media_browse, media_session, media_tv, media_midi, media_projection, uwb, se, view_autofill, view_textclassifier, view_translation 总计 94 个模块,75,342 行代码
This commit is contained in:
1 parent
8ad62be068
commit
506f9ac725
43 files changed
+16704
-23
No files matched your search
@@ -0,0 +1,903 @@
|
||||
from __future__ import annotations
|
||||
|
||||
"""
|
||||
Android RenderScript 组件 — RenderScript, Allocation, Element, Type, Script 等
|
||||
方法签名完全对齐 Android SDK (android.renderscript 包)
|
||||
"""
|
||||
|
||||
import math
|
||||
from typing import Any, Callable, Dict, List, Optional, Tuple, Union
|
||||
|
||||
from .._core import Stub, AndroidOnlyError
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# RenderScript
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class RenderScript(Stub):
|
||||
"""RenderScript — RenderScript 运行时上下文 (桌面仅存根)"""
|
||||
|
||||
# 优先级
|
||||
Priority_LOW = 0
|
||||
Priority_NORMAL = 1
|
||||
Priority_HIGH = 2
|
||||
|
||||
# 上下文类型
|
||||
ContextType_NORMAL = 0
|
||||
ContextType_DEBUG = 1
|
||||
ContextType_PROFILE = 2
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._context_type = RenderScript.ContextType_NORMAL
|
||||
self._error_handler: Optional[Callable] = None
|
||||
self._message_handler: Optional[Callable] = None
|
||||
self._priority = RenderScript.Priority_NORMAL
|
||||
self._initialized = False
|
||||
|
||||
@staticmethod
|
||||
def create(context: Any = None) -> "RenderScript":
|
||||
"""创建 RenderScript 上下文"""
|
||||
rs = RenderScript()
|
||||
rs._initialized = True
|
||||
return rs
|
||||
|
||||
@staticmethod
|
||||
def createMultiContext(context: Any = None,
|
||||
context_type: int = ContextType_NORMAL,
|
||||
flags: int = 0,
|
||||
api_version: int = 0) -> "RenderScript":
|
||||
"""创建多上下文 RenderScript"""
|
||||
rs = RenderScript()
|
||||
rs._context_type = context_type
|
||||
rs._initialized = True
|
||||
return rs
|
||||
|
||||
def setPriority(self, priority: int):
|
||||
"""设置优先级"""
|
||||
self._priority = priority
|
||||
|
||||
def getPriority(self) -> int:
|
||||
return self._priority
|
||||
|
||||
def setErrorHandler(self, handler: Callable):
|
||||
"""设置错误处理器"""
|
||||
self._error_handler = handler
|
||||
|
||||
def setMessageHandler(self, handler: Callable):
|
||||
"""设置消息处理器"""
|
||||
self._message_handler = handler
|
||||
|
||||
def finish(self):
|
||||
"""等待所有挂起渲染完成"""
|
||||
pass
|
||||
|
||||
def destroy(self):
|
||||
"""销毁 RenderScript 上下文"""
|
||||
self._initialized = False
|
||||
|
||||
def getApplicationContext(self) -> Any:
|
||||
return None
|
||||
|
||||
def getErrorHandler(self) -> Optional[Callable]:
|
||||
return self._error_handler
|
||||
|
||||
def getMessageHandler(self) -> Optional[Callable]:
|
||||
return self._message_handler
|
||||
|
||||
def isDestroyed(self) -> bool:
|
||||
return not self._initialized
|
||||
|
||||
def nvLoadAll(self):
|
||||
pass
|
||||
|
||||
def nvLoadFont(self, name: str) -> int:
|
||||
return 0
|
||||
|
||||
def nvLoadProp(self, name: str) -> int:
|
||||
return 0
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"RenderScript(priority={self._priority}, initialized={self._initialized})"
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return id(self) & 0x7FFFFFFF
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
return self is other
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# Element
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class Element(Stub):
|
||||
"""Element — RenderScript 数据类型元素"""
|
||||
|
||||
# 预定义数据类型
|
||||
F32: "Element" = None
|
||||
F64: "Element" = None
|
||||
I8: "Element" = None
|
||||
I16: "Element" = None
|
||||
I32: "Element" = None
|
||||
I64: "Element" = None
|
||||
U8: "Element" = None
|
||||
U16: "Element" = None
|
||||
U32: "Element" = None
|
||||
U64: "Element" = None
|
||||
BOOLEAN: "Element" = None
|
||||
ALLOCATION: "Element" = None
|
||||
A_8: "Element" = None
|
||||
RGB_565: "Element" = None
|
||||
RGBA_4444: "Element" = None
|
||||
RGBA_8888: "Element" = None
|
||||
F32_2: "Element" = None
|
||||
F32_3: "Element" = None
|
||||
F32_4: "Element" = None
|
||||
F64_2: "Element" = None
|
||||
F64_3: "Element" = None
|
||||
F64_4: "Element" = None
|
||||
I8_2: "Element" = None
|
||||
I8_3: "Element" = None
|
||||
I8_4: "Element" = None
|
||||
I16_2: "Element" = None
|
||||
I16_3: "Element" = None
|
||||
I16_4: "Element" = None
|
||||
I32_2: "Element" = None
|
||||
I32_3: "Element" = None
|
||||
I32_4: "Element" = None
|
||||
I64_2: "Element" = None
|
||||
I64_3: "Element" = None
|
||||
I64_4: "Element" = None
|
||||
U8_2: "Element" = None
|
||||
U8_3: "Element" = None
|
||||
U8_4: "Element" = None
|
||||
U16_2: "Element" = None
|
||||
U16_3: "Element" = None
|
||||
U16_4: "Element" = None
|
||||
U32_2: "Element" = None
|
||||
U32_3: "Element" = None
|
||||
U32_4: "Element" = None
|
||||
U64_2: "Element" = None
|
||||
U64_3: "Element" = None
|
||||
U64_4: "Element" = None
|
||||
|
||||
# 数据类型
|
||||
DataType = type("DataType", (), {
|
||||
"NONE": 0, "FLOAT_32": 1, "FLOAT_64": 2,
|
||||
"SIGNED_8": 3, "SIGNED_16": 4, "SIGNED_32": 5, "SIGNED_64": 6,
|
||||
"UNSIGNED_8": 7, "UNSIGNED_16": 8, "UNSIGNED_32": 9, "UNSIGNED_64": 10,
|
||||
"BOOLEAN": 11, "UNSIGNED_5_6_5": 12, "UNSIGNED_5_5_5_1": 13,
|
||||
"UNSIGNED_4_4_4_4": 14, "MATRIX_4X4": 15, "MATRIX_3X3": 16,
|
||||
"UNSIGNED_2_10_10_10": 17, "RS_ELEMENT": 18,
|
||||
})
|
||||
|
||||
# 数据类型大小
|
||||
DataType = DataType()
|
||||
|
||||
def __init__(self, rs: Optional[RenderScript] = None, data_type: int = 0,
|
||||
vector_size: int = 1):
|
||||
super().__init__()
|
||||
self._rs = rs
|
||||
self._data_type = data_type
|
||||
self._vector_size = vector_size
|
||||
self._element_size = self._compute_size()
|
||||
|
||||
def _compute_size(self) -> int:
|
||||
base_sizes = {
|
||||
Element.DataType.FLOAT_32: 4, Element.DataType.FLOAT_64: 8,
|
||||
Element.DataType.SIGNED_8: 1, Element.DataType.SIGNED_16: 2,
|
||||
Element.DataType.SIGNED_32: 4, Element.DataType.SIGNED_64: 8,
|
||||
Element.DataType.UNSIGNED_8: 1, Element.DataType.UNSIGNED_16: 2,
|
||||
Element.DataType.UNSIGNED_32: 4, Element.DataType.UNSIGNED_64: 8,
|
||||
Element.DataType.BOOLEAN: 1,
|
||||
Element.DataType.UNSIGNED_5_6_5: 2,
|
||||
Element.DataType.UNSIGNED_5_5_5_1: 2,
|
||||
Element.DataType.UNSIGNED_4_4_4_4: 2,
|
||||
Element.DataType.MATRIX_4X4: 64,
|
||||
Element.DataType.MATRIX_3X3: 36,
|
||||
Element.DataType.RS_ELEMENT: 4,
|
||||
}
|
||||
return base_sizes.get(self._data_type, 4) * self._vector_size
|
||||
|
||||
def getBytesSize(self) -> int:
|
||||
return self._element_size
|
||||
|
||||
def getVectorSize(self) -> int:
|
||||
return self._vector_size
|
||||
|
||||
def getDataType(self) -> int:
|
||||
return self._data_type
|
||||
|
||||
def isCompatible(self, e: "Element") -> bool:
|
||||
return self._data_type == e._data_type and self._vector_size == e._vector_size
|
||||
|
||||
def getSubElement(self, index: int) -> Optional["Element"]:
|
||||
return None
|
||||
|
||||
def getSubElementCount(self) -> int:
|
||||
return 0
|
||||
|
||||
def getSubElementArraySize(self, index: int) -> int:
|
||||
return 0
|
||||
|
||||
def getSubElementOffsetBytes(self, index: int) -> int:
|
||||
return 0
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"Element(dataType={self._data_type}, vectorSize={self._vector_size})"
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return hash((self._data_type, self._vector_size)) & 0x7FFFFFFF
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
if not isinstance(other, Element):
|
||||
return False
|
||||
return self._data_type == other._data_type and self._vector_size == other._vector_size
|
||||
|
||||
@staticmethod
|
||||
def BOOL(rs: RenderScript) -> "Element":
|
||||
return Element(rs, Element.DataType.BOOLEAN, 1)
|
||||
|
||||
@staticmethod
|
||||
def U8(rs: RenderScript) -> "Element":
|
||||
return Element(rs, Element.DataType.UNSIGNED_8, 1)
|
||||
|
||||
@staticmethod
|
||||
def I8(rs: RenderScript) -> "Element":
|
||||
return Element(rs, Element.DataType.SIGNED_8, 1)
|
||||
|
||||
@staticmethod
|
||||
def U16(rs: RenderScript) -> "Element":
|
||||
return Element(rs, Element.DataType.UNSIGNED_16, 1)
|
||||
|
||||
@staticmethod
|
||||
def I16(rs: RenderScript) -> "Element":
|
||||
return Element(rs, Element.DataType.SIGNED_16, 1)
|
||||
|
||||
@staticmethod
|
||||
def U32(rs: RenderScript) -> "Element":
|
||||
return Element(rs, Element.DataType.UNSIGNED_32, 1)
|
||||
|
||||
@staticmethod
|
||||
def I32(rs: RenderScript) -> "Element":
|
||||
return Element(rs, Element.DataType.SIGNED_32, 1)
|
||||
|
||||
@staticmethod
|
||||
def U64(rs: RenderScript) -> "Element":
|
||||
return Element(rs, Element.DataType.UNSIGNED_64, 1)
|
||||
|
||||
@staticmethod
|
||||
def I64(rs: RenderScript) -> "Element":
|
||||
return Element(rs, Element.DataType.SIGNED_64, 1)
|
||||
|
||||
@staticmethod
|
||||
def F32(rs: RenderScript) -> "Element":
|
||||
return Element(rs, Element.DataType.FLOAT_32, 1)
|
||||
|
||||
@staticmethod
|
||||
def F64(rs: RenderScript) -> "Element":
|
||||
return Element(rs, Element.DataType.FLOAT_64, 1)
|
||||
|
||||
@staticmethod
|
||||
def createVector(rs: RenderScript, data_type: int, size: int) -> "Element":
|
||||
return Element(rs, data_type, size)
|
||||
|
||||
@staticmethod
|
||||
def createPixel(rs: RenderScript, data_type: int, pixel_type: int) -> "Element":
|
||||
return Element(rs, data_type, 4)
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# Type
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class Type(Stub):
|
||||
"""Type — RenderScript 内存分配类型"""
|
||||
|
||||
CubemapFace = type("CubemapFace", (), {
|
||||
"POSITIVE_X": 0, "NEGATIVE_X": 1,
|
||||
"POSITIVE_Y": 2, "NEGATIVE_Y": 3,
|
||||
"POSITIVE_Z": 4, "NEGATIVE_Z": 5,
|
||||
})
|
||||
|
||||
def __init__(self, rs: Optional[RenderScript] = None,
|
||||
element: Optional[Element] = None,
|
||||
dim_x: int = 0, dim_y: int = 0, dim_z: int = 0,
|
||||
mipmaps: bool = False, faces: bool = False):
|
||||
super().__init__()
|
||||
self._rs = rs
|
||||
self._element = element
|
||||
self._dim_x = dim_x
|
||||
self._dim_y = dim_y
|
||||
self._dim_z = dim_z
|
||||
self._mipmaps = mipmaps
|
||||
self._faces = faces
|
||||
self._yuv_format = 0
|
||||
|
||||
def getElement(self) -> Optional[Element]:
|
||||
return self._element
|
||||
|
||||
def getX(self) -> int:
|
||||
return self._dim_x
|
||||
|
||||
def getY(self) -> int:
|
||||
return self._dim_y
|
||||
|
||||
def getZ(self) -> int:
|
||||
return self._dim_z
|
||||
|
||||
def getCount(self) -> int:
|
||||
return self._dim_x * max(self._dim_y, 1) * max(self._dim_z, 1)
|
||||
|
||||
def hasMipmaps(self) -> bool:
|
||||
return self._mipmaps
|
||||
|
||||
def hasFaces(self) -> bool:
|
||||
return self._faces
|
||||
|
||||
def getYuvFormat(self) -> int:
|
||||
return self._yuv_format
|
||||
|
||||
def setYuvFormat(self, yuv_format: int):
|
||||
self._yuv_format = yuv_format
|
||||
|
||||
def toString(self) -> str:
|
||||
return (f"Type(element={self._element}, dims={self._dim_x}x{self._dim_y}"
|
||||
f"x{self._dim_z}, mipmaps={self._mipmaps})")
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return hash((self._dim_x, self._dim_y, self._dim_z)) & 0x7FFFFFFF
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
if not isinstance(other, Type):
|
||||
return False
|
||||
return (self._dim_x == other._dim_x and self._dim_y == other._dim_y
|
||||
and self._dim_z == other._dim_z)
|
||||
|
||||
# ── Builder ──
|
||||
|
||||
class Builder(Stub):
|
||||
"""Builder — Type 构建器"""
|
||||
|
||||
def __init__(self, rs: RenderScript, element: Element):
|
||||
super().__init__()
|
||||
self._rs = rs
|
||||
self._element = element
|
||||
self._dim_x = 0
|
||||
self._dim_y = 0
|
||||
self._dim_z = 0
|
||||
self._mipmaps = False
|
||||
self._faces = False
|
||||
self._yuv_format = 0
|
||||
|
||||
def setX(self, value: int) -> "Type.Builder":
|
||||
self._dim_x = value
|
||||
return self
|
||||
|
||||
def setY(self, value: int) -> "Type.Builder":
|
||||
self._dim_y = value
|
||||
return self
|
||||
|
||||
def setZ(self, value: int) -> "Type.Builder":
|
||||
self._dim_z = value
|
||||
return self
|
||||
|
||||
def setMipmaps(self, enable: bool) -> "Type.Builder":
|
||||
self._mipmaps = enable
|
||||
return self
|
||||
|
||||
def setFaces(self, enable: bool) -> "Type.Builder":
|
||||
self._faces = enable
|
||||
return self
|
||||
|
||||
def setYuvFormat(self, yuv_format: int) -> "Type.Builder":
|
||||
self._yuv_format = yuv_format
|
||||
return self
|
||||
|
||||
def create(self) -> Type:
|
||||
t = Type(self._rs, self._element, self._dim_x, self._dim_y,
|
||||
self._dim_z, self._mipmaps, self._faces)
|
||||
t._yuv_format = self._yuv_format
|
||||
return t
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# Allocation
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class Allocation(Stub):
|
||||
"""Allocation — RenderScript 内存分配"""
|
||||
|
||||
# 使用类型
|
||||
USAGE_SCRIPT = 0x0001
|
||||
USAGE_GRAPHICS_TEXTURE = 0x0002
|
||||
USAGE_GRAPHICS_VERTEX = 0x0004
|
||||
USAGE_GRAPHICS_CONSTANTS = 0x0008
|
||||
USAGE_GRAPHICS_RENDER_TARGET = 0x0010
|
||||
USAGE_IO_INPUT = 0x0020
|
||||
USAGE_IO_OUTPUT = 0x0040
|
||||
USAGE_SHARED = 0x0080
|
||||
|
||||
# Mipmap 控制
|
||||
MIPMAP_FULL = 0
|
||||
MIPMAP_ON_SYNC_TO_TEXTURE = 1
|
||||
|
||||
def __init__(self, rs: Optional[RenderScript] = None,
|
||||
type_: Optional[Type] = None,
|
||||
usage: int = USAGE_SCRIPT):
|
||||
super().__init__()
|
||||
self._rs = rs
|
||||
self._type = type_
|
||||
self._usage = usage
|
||||
self._data: Any = None
|
||||
self._element_size = type_.getElement().getBytesSize() if type_ and type_.getElement() else 0
|
||||
|
||||
@staticmethod
|
||||
def createTyped(rs: RenderScript, type_: Type,
|
||||
usage: int = USAGE_SCRIPT) -> "Allocation":
|
||||
"""创建分配"""
|
||||
alloc = Allocation(rs, type_, usage)
|
||||
total_size = type_.getCount() * type_.getElement().getBytesSize() if type_.getElement() else 0
|
||||
alloc._data = bytearray(total_size)
|
||||
return alloc
|
||||
|
||||
@staticmethod
|
||||
def createFromBitmap(rs: RenderScript, bitmap: Any,
|
||||
usage: int = USAGE_SCRIPT) -> "Allocation":
|
||||
"""从位图创建分配"""
|
||||
# 尝试获取位图尺寸
|
||||
width, height = 0, 0
|
||||
try:
|
||||
width = bitmap.getWidth() if hasattr(bitmap, 'getWidth') else 0
|
||||
height = bitmap.getHeight() if hasattr(bitmap, 'getHeight') else 0
|
||||
except Exception:
|
||||
pass
|
||||
element = Element(rs, Element.DataType.UNSIGNED_8, 4)
|
||||
type_ = Type(rs, element, width, height)
|
||||
alloc = Allocation(rs, type_, usage)
|
||||
alloc._data = bytearray(width * height * 4)
|
||||
return alloc
|
||||
|
||||
@staticmethod
|
||||
def createFromBitmapBoxed(rs: RenderScript, bitmap: Any,
|
||||
usage: int = USAGE_SCRIPT) -> "Allocation":
|
||||
return Allocation.createFromBitmap(rs, bitmap, usage)
|
||||
|
||||
def copyFrom(self, data: Any):
|
||||
"""从数组或位图复制数据"""
|
||||
if isinstance(data, (bytes, bytearray)):
|
||||
self._data = bytearray(data)
|
||||
elif hasattr(data, '__iter__'):
|
||||
import struct
|
||||
try:
|
||||
self._data = bytearray(struct.pack(f'<{len(list(data))}f',
|
||||
*[float(v) for v in data]))
|
||||
except Exception:
|
||||
self._data = bytearray(len(list(data)) * 4)
|
||||
else:
|
||||
self._data = bytearray(1024)
|
||||
|
||||
def copyTo(self, data: Any):
|
||||
"""将数据复制到目标"""
|
||||
if isinstance(data, bytearray) and self._data:
|
||||
data[:] = self._data
|
||||
elif isinstance(data, list):
|
||||
data.clear()
|
||||
if self._data:
|
||||
for i in range(0, len(self._data), 4):
|
||||
data.append(int.from_bytes(self._data[i:i+4], 'little'))
|
||||
|
||||
def resize(self, dim_x: int):
|
||||
"""重新调整分配大小"""
|
||||
if self._type:
|
||||
self._type._dim_x = dim_x
|
||||
self._data = bytearray(self._type.getCount() * self._element_size)
|
||||
|
||||
def getType(self) -> Optional[Type]:
|
||||
return self._type
|
||||
|
||||
def getUsage(self) -> int:
|
||||
return self._usage
|
||||
|
||||
def getElement(self) -> Optional[Element]:
|
||||
return self._type.getElement() if self._type else None
|
||||
|
||||
def syncAll(self, src_location: int):
|
||||
pass
|
||||
|
||||
def destroy(self):
|
||||
self._data = None
|
||||
|
||||
def toString(self) -> str:
|
||||
return (f"Allocation(type={self._type}, usage={self._usage}, "
|
||||
f"data_size={len(self._data) if self._data else 0})")
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return id(self) & 0x7FFFFFFF
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
return self is other
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# Matrix4f
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class Matrix4f(Stub):
|
||||
"""Matrix4f — 4x4 浮点矩阵"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._matrix = [0.0] * 16
|
||||
self._matrix[0] = 1.0 # 单位矩阵
|
||||
self._matrix[5] = 1.0
|
||||
self._matrix[10] = 1.0
|
||||
self._matrix[15] = 1.0
|
||||
|
||||
def getArray(self) -> List[float]:
|
||||
return list(self._matrix)
|
||||
|
||||
def setArray(self, array: List[float]):
|
||||
if len(array) >= 16:
|
||||
self._matrix = list(array[:16])
|
||||
|
||||
def loadIdentity(self):
|
||||
self._matrix = [0.0] * 16
|
||||
self._matrix[0] = 1.0
|
||||
self._matrix[5] = 1.0
|
||||
self._matrix[10] = 1.0
|
||||
self._matrix[15] = 1.0
|
||||
|
||||
def load(self, src: "Matrix4f"):
|
||||
self._matrix = list(src._matrix)
|
||||
|
||||
def loadRotate(self, rot: float, x: float, y: float, z: float):
|
||||
angle_rad = math.radians(rot)
|
||||
c = math.cos(angle_rad)
|
||||
s = math.sin(angle_rad)
|
||||
self.loadIdentity()
|
||||
if x == 1 and y == 0 and z == 0:
|
||||
self._matrix[5] = c
|
||||
self._matrix[6] = -s
|
||||
self._matrix[9] = s
|
||||
self._matrix[10] = c
|
||||
elif x == 0 and y == 1 and z == 0:
|
||||
self._matrix[0] = c
|
||||
self._matrix[2] = s
|
||||
self._matrix[8] = -s
|
||||
self._matrix[10] = c
|
||||
elif x == 0 and y == 0 and z == 1:
|
||||
self._matrix[0] = c
|
||||
self._matrix[1] = -s
|
||||
self._matrix[4] = s
|
||||
self._matrix[5] = c
|
||||
|
||||
def loadScale(self, x: float, y: float, z: float):
|
||||
self.loadIdentity()
|
||||
self._matrix[0] = x
|
||||
self._matrix[5] = y
|
||||
self._matrix[10] = z
|
||||
|
||||
def loadTranslate(self, x: float, y: float, z: float):
|
||||
self.loadIdentity()
|
||||
self._matrix[12] = x
|
||||
self._matrix[13] = y
|
||||
self._matrix[14] = z
|
||||
|
||||
def loadMultiply(self, lhs: "Matrix4f", rhs: "Matrix4f"):
|
||||
for i in range(4):
|
||||
for j in range(4):
|
||||
self._matrix[i * 4 + j] = sum(
|
||||
lhs._matrix[i * 4 + k] * rhs._matrix[k * 4 + j]
|
||||
for k in range(4)
|
||||
)
|
||||
|
||||
def multiply(self, rhs: "Matrix4f"):
|
||||
result = [0.0] * 16
|
||||
for i in range(4):
|
||||
for j in range(4):
|
||||
result[i * 4 + j] = sum(
|
||||
self._matrix[i * 4 + k] * rhs._matrix[k * 4 + j]
|
||||
for k in range(4)
|
||||
)
|
||||
self._matrix = result
|
||||
|
||||
def transpose(self):
|
||||
for i in range(4):
|
||||
for j in range(i + 1, 4):
|
||||
self._matrix[i * 4 + j], self._matrix[j * 4 + i] = \
|
||||
self._matrix[j * 4 + i], self._matrix[i * 4 + j]
|
||||
|
||||
def toString(self) -> str:
|
||||
rows = []
|
||||
for i in range(4):
|
||||
row = self._matrix[i*4:(i+1)*4]
|
||||
rows.append(f"[{', '.join(f'{v:.4f}' for v in row)}]")
|
||||
return f"Matrix4f({', '.join(rows)})"
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return hash(tuple(self._matrix)) & 0x7FFFFFFF
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
if not isinstance(other, Matrix4f):
|
||||
return False
|
||||
return self._matrix == other._matrix
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# Matrix3f
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class Matrix3f(Stub):
|
||||
"""Matrix3f — 3x3 浮点矩阵"""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._matrix = [0.0] * 9
|
||||
self._matrix[0] = 1.0
|
||||
self._matrix[4] = 1.0
|
||||
self._matrix[8] = 1.0
|
||||
|
||||
def getArray(self) -> List[float]:
|
||||
return list(self._matrix)
|
||||
|
||||
def setArray(self, array: List[float]):
|
||||
if len(array) >= 9:
|
||||
self._matrix = list(array[:9])
|
||||
|
||||
def loadIdentity(self):
|
||||
self._matrix = [0.0] * 9
|
||||
self._matrix[0] = 1.0
|
||||
self._matrix[4] = 1.0
|
||||
self._matrix[8] = 1.0
|
||||
|
||||
def load(self, src: "Matrix3f"):
|
||||
self._matrix = list(src._matrix)
|
||||
|
||||
def loadMultiply(self, lhs: "Matrix3f", rhs: "Matrix3f"):
|
||||
for i in range(3):
|
||||
for j in range(3):
|
||||
self._matrix[i * 3 + j] = sum(
|
||||
lhs._matrix[i * 3 + k] * rhs._matrix[k * 3 + j]
|
||||
for k in range(3)
|
||||
)
|
||||
|
||||
def multiply(self, rhs: "Matrix3f"):
|
||||
result = [0.0] * 9
|
||||
for i in range(3):
|
||||
for j in range(3):
|
||||
result[i * 3 + j] = sum(
|
||||
self._matrix[i * 3 + k] * rhs._matrix[k * 3 + j]
|
||||
for k in range(3)
|
||||
)
|
||||
self._matrix = result
|
||||
|
||||
def transpose(self):
|
||||
for i in range(3):
|
||||
for j in range(i + 1, 3):
|
||||
self._matrix[i * 3 + j], self._matrix[j * 3 + i] = \
|
||||
self._matrix[j * 3 + i], self._matrix[i * 3 + j]
|
||||
|
||||
def toString(self) -> str:
|
||||
rows = []
|
||||
for i in range(3):
|
||||
row = self._matrix[i*3:(i+1)*3]
|
||||
rows.append(f"[{', '.join(f'{v:.4f}' for v in row)}]")
|
||||
return f"Matrix3f({', '.join(rows)})"
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return hash(tuple(self._matrix)) & 0x7FFFFFFF
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
if not isinstance(other, Matrix3f):
|
||||
return False
|
||||
return self._matrix == other._matrix
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# Script (base)
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class Script(Stub):
|
||||
"""Script — RenderScript 脚本基类"""
|
||||
|
||||
def __init__(self, rs: Optional[RenderScript] = None):
|
||||
super().__init__()
|
||||
self._rs = rs
|
||||
self._kernel_groups: List[Any] = []
|
||||
|
||||
def setVar(self, index: int, value: Any):
|
||||
"""设置脚本变量"""
|
||||
pass
|
||||
|
||||
def getVar(self, index: int) -> Any:
|
||||
return None
|
||||
|
||||
def setTimeZone(self, timezone: str):
|
||||
pass
|
||||
|
||||
def forEach(self, slot: int, ains: List[Allocation],
|
||||
aout: Allocation, vdata: Any = None):
|
||||
"""执行 forEach 内核"""
|
||||
raise AndroidOnlyError("Script.forEach() 仅在 Android (RenderScript) 设备上可用")
|
||||
|
||||
def invoke(self, slot: int):
|
||||
"""调用可调用函数"""
|
||||
pass
|
||||
|
||||
def bindAllocation(self, va: Allocation, slot: int):
|
||||
"""绑定分配"""
|
||||
pass
|
||||
|
||||
def destroy(self):
|
||||
pass
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"Script@{hex(id(self))}"
|
||||
|
||||
def hashCode(self) -> int:
|
||||
return id(self) & 0x7FFFFFFF
|
||||
|
||||
def equals(self, other) -> bool:
|
||||
return self is other
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# ScriptC
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class ScriptC(Script):
|
||||
"""ScriptC — 编译的 RenderScript 内核脚本"""
|
||||
|
||||
def __init__(self, rs: RenderScript, resource_id: int = 0):
|
||||
super().__init__(rs)
|
||||
self._resource_id = resource_id
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"ScriptC(resourceId={self._resource_id})"
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# ScriptIntrinsicBlur
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class ScriptIntrinsicBlur(Script):
|
||||
"""ScriptIntrinsicBlur — 高斯模糊内在函数"""
|
||||
|
||||
def __init__(self, rs: RenderScript):
|
||||
super().__init__(rs)
|
||||
self._radius: float = 5.0
|
||||
self._input: Optional[Allocation] = None
|
||||
|
||||
@staticmethod
|
||||
def create(rs: RenderScript, e: Element) -> "ScriptIntrinsicBlur":
|
||||
"""创建模糊内在函数"""
|
||||
return ScriptIntrinsicBlur(rs)
|
||||
|
||||
def setRadius(self, radius: float):
|
||||
"""设置模糊半径"""
|
||||
self._radius = max(0.0, min(radius, 25.0))
|
||||
|
||||
def setInput(self, alloc: Allocation):
|
||||
"""设置输入分配"""
|
||||
self._input = alloc
|
||||
|
||||
def forEach(self, aout: Allocation):
|
||||
"""执行模糊"""
|
||||
if self._input and aout:
|
||||
pass # 在桌面环境不执行实际模糊
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"ScriptIntrinsicBlur(radius={self._radius})"
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# ScriptIntrinsicConvolve3x3
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class ScriptIntrinsicConvolve3x3(Script):
|
||||
"""ScriptIntrinsicConvolve3x3 — 3x3 卷积内在函数"""
|
||||
|
||||
def __init__(self, rs: RenderScript):
|
||||
super().__init__(rs)
|
||||
self._coefficients: List[float] = [0.0] * 9
|
||||
self._input: Optional[Allocation] = None
|
||||
|
||||
@staticmethod
|
||||
def create(rs: RenderScript, e: Element) -> "ScriptIntrinsicConvolve3x3":
|
||||
"""创建卷积内在函数"""
|
||||
return ScriptIntrinsicConvolve3x3(rs)
|
||||
|
||||
def setCoefficients(self, coeffs: List[float]):
|
||||
"""设置卷积系数"""
|
||||
for i in range(min(len(coeffs), 9)):
|
||||
self._coefficients[i] = coeffs[i]
|
||||
|
||||
def setInput(self, alloc: Allocation):
|
||||
"""设置输入分配"""
|
||||
self._input = alloc
|
||||
|
||||
def forEach(self, aout: Allocation):
|
||||
"""执行卷积"""
|
||||
pass
|
||||
|
||||
def toString(self) -> str:
|
||||
return f"ScriptIntrinsicConvolve3x3(coefficients={self._coefficients})"
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# 初始化 Element 静态实例
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
def _init_elements():
|
||||
"""初始化 Element 预定义实例(在模块导入时调用)"""
|
||||
rs = RenderScript.create()
|
||||
Element.F32 = Element.F32(rs)
|
||||
Element.F64 = Element.F64(rs)
|
||||
Element.I8 = Element.I8(rs)
|
||||
Element.I16 = Element.I16(rs)
|
||||
Element.I32 = Element.I32(rs)
|
||||
Element.I64 = Element.I64(rs)
|
||||
Element.U8 = Element.U8(rs)
|
||||
Element.U16 = Element.U16(rs)
|
||||
Element.U32 = Element.U32(rs)
|
||||
Element.U64 = Element.U64(rs)
|
||||
Element.BOOLEAN = Element.BOOL(rs)
|
||||
Element.ALLOCATION = Element(rs, Element.DataType.RS_ELEMENT, 1)
|
||||
Element.A_8 = Element.createPixel(rs, Element.DataType.UNSIGNED_8, 1)
|
||||
Element.RGB_565 = Element.createPixel(rs, Element.DataType.UNSIGNED_5_6_5, 3)
|
||||
Element.RGBA_4444 = Element.createPixel(rs, Element.DataType.UNSIGNED_4_4_4_4, 4)
|
||||
Element.RGBA_8888 = Element.createPixel(rs, Element.DataType.UNSIGNED_8, 4)
|
||||
Element.F32_2 = Element.createVector(rs, Element.DataType.FLOAT_32, 2)
|
||||
Element.F32_3 = Element.createVector(rs, Element.DataType.FLOAT_32, 3)
|
||||
Element.F32_4 = Element.createVector(rs, Element.DataType.FLOAT_32, 4)
|
||||
Element.F64_2 = Element.createVector(rs, Element.DataType.FLOAT_64, 2)
|
||||
Element.F64_3 = Element.createVector(rs, Element.DataType.FLOAT_64, 3)
|
||||
Element.F64_4 = Element.createVector(rs, Element.DataType.FLOAT_64, 4)
|
||||
Element.I8_2 = Element.createVector(rs, Element.DataType.SIGNED_8, 2)
|
||||
Element.I8_3 = Element.createVector(rs, Element.DataType.SIGNED_8, 3)
|
||||
Element.I8_4 = Element.createVector(rs, Element.DataType.SIGNED_8, 4)
|
||||
Element.I16_2 = Element.createVector(rs, Element.DataType.SIGNED_16, 2)
|
||||
Element.I16_3 = Element.createVector(rs, Element.DataType.SIGNED_16, 3)
|
||||
Element.I16_4 = Element.createVector(rs, Element.DataType.SIGNED_16, 4)
|
||||
Element.I32_2 = Element.createVector(rs, Element.DataType.SIGNED_32, 2)
|
||||
Element.I32_3 = Element.createVector(rs, Element.DataType.SIGNED_32, 3)
|
||||
Element.I32_4 = Element.createVector(rs, Element.DataType.SIGNED_32, 4)
|
||||
Element.I64_2 = Element.createVector(rs, Element.DataType.SIGNED_64, 2)
|
||||
Element.I64_3 = Element.createVector(rs, Element.DataType.SIGNED_64, 3)
|
||||
Element.I64_4 = Element.createVector(rs, Element.DataType.SIGNED_64, 4)
|
||||
Element.U8_2 = Element.createVector(rs, Element.DataType.UNSIGNED_8, 2)
|
||||
Element.U8_3 = Element.createVector(rs, Element.DataType.UNSIGNED_8, 3)
|
||||
Element.U8_4 = Element.createVector(rs, Element.DataType.UNSIGNED_8, 4)
|
||||
Element.U16_2 = Element.createVector(rs, Element.DataType.UNSIGNED_16, 2)
|
||||
Element.U16_3 = Element.createVector(rs, Element.DataType.UNSIGNED_16, 3)
|
||||
Element.U16_4 = Element.createVector(rs, Element.DataType.UNSIGNED_16, 4)
|
||||
Element.U32_2 = Element.createVector(rs, Element.DataType.UNSIGNED_32, 2)
|
||||
Element.U32_3 = Element.createVector(rs, Element.DataType.UNSIGNED_32, 3)
|
||||
Element.U32_4 = Element.createVector(rs, Element.DataType.UNSIGNED_32, 4)
|
||||
Element.U64_2 = Element.createVector(rs, Element.DataType.UNSIGNED_64, 2)
|
||||
Element.U64_3 = Element.createVector(rs, Element.DataType.UNSIGNED_64, 3)
|
||||
Element.U64_4 = Element.createVector(rs, Element.DataType.UNSIGNED_64, 4)
|
||||
|
||||
|
||||
_init_elements()
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# __all__
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
__all__ = [
|
||||
"RenderScript",
|
||||
"Allocation",
|
||||
"Element",
|
||||
"Type",
|
||||
"Script",
|
||||
"ScriptIntrinsicBlur",
|
||||
"ScriptIntrinsicConvolve3x3",
|
||||
"ScriptC",
|
||||
"Matrix4f",
|
||||
"Matrix3f",
|
||||
]
|
||||
Reference in new issue
Block a user