修改calman灰阶点击异常、修改色准结果显示异常
This commit is contained in:
@@ -18,6 +18,7 @@ SDK 调用直接搬入本模块,届时可删除旧 ``UCDController`` 文件。
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from contextlib import contextmanager
|
||||
import logging
|
||||
import threading
|
||||
from abc import ABC, abstractmethod
|
||||
@@ -48,6 +49,8 @@ if TYPE_CHECKING:
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
_DEVICE_LOCK_TIMEOUT_SECONDS = 8.0
|
||||
|
||||
|
||||
# ─── §1 DeviceInfo / list_devices ────────────────────────────────
|
||||
|
||||
@@ -154,12 +157,50 @@ class UCD323Device(IUcdDevice):
|
||||
self._info: DeviceInfo | None = None
|
||||
self._interface: Interface = Interface.HDMI
|
||||
self._lock = threading.RLock()
|
||||
self._lock_owner_tid: int | None = None
|
||||
self._lock_owner_name: str | None = None
|
||||
|
||||
self._curr_signal: SignalFormat | None = None
|
||||
self._curr_timing: TimingSpec | None = None
|
||||
self._curr_pattern: PatternSpec | None = None
|
||||
self._last_applied: tuple[SignalFormat, TimingSpec] | None = None
|
||||
|
||||
@contextmanager
|
||||
def _acquire_device_lock(self, op_name: str):
|
||||
current = threading.current_thread()
|
||||
log.info(
|
||||
"UCD323Device.%s acquiring lock timeout=%.1fs tid=%s thread=%s owner_tid=%s owner_thread=%s",
|
||||
op_name,
|
||||
_DEVICE_LOCK_TIMEOUT_SECONDS,
|
||||
threading.get_ident(),
|
||||
current.name,
|
||||
self._lock_owner_tid,
|
||||
self._lock_owner_name,
|
||||
)
|
||||
acquired = self._lock.acquire(timeout=_DEVICE_LOCK_TIMEOUT_SECONDS)
|
||||
if not acquired:
|
||||
raise UcdStateError(
|
||||
"UCD device busy: lock timeout in "
|
||||
f"UCD323Device.{op_name}, "
|
||||
f"owner_tid={self._lock_owner_tid}, owner_thread={self._lock_owner_name}"
|
||||
)
|
||||
prev_owner_tid = self._lock_owner_tid
|
||||
prev_owner_name = self._lock_owner_name
|
||||
self._lock_owner_tid = threading.get_ident()
|
||||
self._lock_owner_name = current.name
|
||||
log.info(
|
||||
"UCD323Device.%s lock acquired tid=%s thread=%s",
|
||||
op_name,
|
||||
self._lock_owner_tid,
|
||||
self._lock_owner_name,
|
||||
)
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
self._lock_owner_tid = prev_owner_tid
|
||||
self._lock_owner_name = prev_owner_name
|
||||
self._lock.release()
|
||||
|
||||
# -- 读访问 --------------------------------------------------
|
||||
|
||||
@property
|
||||
@@ -181,7 +222,7 @@ class UCD323Device(IUcdDevice):
|
||||
# -- 生命周期 ------------------------------------------------
|
||||
|
||||
def open(self, info: DeviceInfo, *, interface: Interface = Interface.HDMI) -> None:
|
||||
with self._lock:
|
||||
with self._acquire_device_lock("open"):
|
||||
assert_transition(self._state, UcdState.OPENED)
|
||||
if interface is not Interface.HDMI:
|
||||
# Phase 1:底层 UCDController.open() 写死了 HDMISource。
|
||||
@@ -200,7 +241,7 @@ class UCD323Device(IUcdDevice):
|
||||
self._bus.publish(ConnectionChanged(True, info.serial))
|
||||
|
||||
def close(self) -> None:
|
||||
with self._lock:
|
||||
with self._acquire_device_lock("close"):
|
||||
if self._state == UcdState.CLOSED:
|
||||
return
|
||||
try:
|
||||
@@ -219,7 +260,7 @@ class UCD323Device(IUcdDevice):
|
||||
# -- 配置 ----------------------------------------------------
|
||||
|
||||
def configure(self, signal: SignalFormat, timing: TimingSpec) -> bool:
|
||||
with self._lock:
|
||||
with self._acquire_device_lock("configure"):
|
||||
if self._state == UcdState.CLOSED:
|
||||
raise UcdNotConnected("UCD 未连接,无法 configure")
|
||||
try:
|
||||
@@ -249,7 +290,7 @@ class UCD323Device(IUcdDevice):
|
||||
return (signal, timing) != self._last_applied
|
||||
|
||||
def set_pattern(self, pattern: PatternSpec) -> None:
|
||||
with self._lock:
|
||||
with self._acquire_device_lock("set_pattern"):
|
||||
# Phase 2 过渡:允许从 OPENED 直接 set_pattern——遗留路径
|
||||
# (test_runner 等)通过旧 controller.apply_signal_format 写入
|
||||
# 信号格式,未经过本设备的 configure。此时 self._state 仍为
|
||||
@@ -260,7 +301,7 @@ class UCD323Device(IUcdDevice):
|
||||
# 仅本地暂存,真正写硬件在 apply()
|
||||
|
||||
def apply(self) -> None:
|
||||
with self._lock:
|
||||
with self._acquire_device_lock("apply"):
|
||||
if self._state == UcdState.CLOSED:
|
||||
raise UcdNotConnected("UCD 未连接,无法 apply")
|
||||
if self._curr_pattern is None:
|
||||
@@ -268,7 +309,9 @@ class UCD323Device(IUcdDevice):
|
||||
try:
|
||||
ok = self._apply_pattern_via_controller(self._curr_pattern)
|
||||
except Exception as exc: # noqa: BLE001
|
||||
raise UcdSdkError("apply 异常") from exc
|
||||
raise UcdSdkError(
|
||||
f"apply 异常: {type(exc).__name__}: {exc}"
|
||||
) from exc
|
||||
if not ok:
|
||||
raise UcdApplyFailed(
|
||||
f"apply 失败: pattern={self._curr_pattern.kind.value}"
|
||||
@@ -333,7 +376,21 @@ class UCD323Device(IUcdDevice):
|
||||
|
||||
if not self._controller.set_pattern(video_pattern, params):
|
||||
raise UcdApplyFailed("controller.set_pattern 返回 False")
|
||||
return bool(self._controller.run())
|
||||
# Skip apply_video_mode() (i.e. pg.set_vm) – the video format is already
|
||||
# configured by the main signal panel and re-applying it blocks until the
|
||||
# device re-locks, causing an apparent UI freeze for pattern-only sends.
|
||||
if not self._controller.apply_pattern():
|
||||
raise UcdApplyFailed("controller.apply_pattern 返回 False")
|
||||
if getattr(self._controller, "current_timing", None) is None:
|
||||
raise UcdConfigError(
|
||||
"current_timing is None; please apply selected test profile/timing before sending pattern"
|
||||
)
|
||||
try:
|
||||
pg, _ = self._controller.get_tx_modules()
|
||||
pg.apply()
|
||||
except Exception as exc:
|
||||
raise UcdSdkError("pg.apply() 失败") from exc
|
||||
return True
|
||||
|
||||
|
||||
def _colorimetry_to_legacy_key(signal: SignalFormat) -> str:
|
||||
|
||||
Reference in New Issue
Block a user