mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-09-04 15:13:58 +08:00
237 lines
7.5 KiB
Python
237 lines
7.5 KiB
Python
import gc
|
|
from types import SimpleNamespace
|
|
import weakref
|
|
|
|
import pytest
|
|
|
|
from openpilot.selfdrive.ui.onroad import cameraview as big_cameraview
|
|
from openpilot.selfdrive.ui.onroad import augmented_road_view as big_augmented_road_view
|
|
from openpilot.selfdrive.ui.mici.onroad import augmented_road_view as mici_augmented_road_view
|
|
|
|
|
|
def test_road_transition_releases_camera_buffers(monkeypatch):
|
|
module = big_cameraview
|
|
|
|
class FakeClient:
|
|
pass
|
|
|
|
view = module.CameraView.__new__(module.CameraView)
|
|
old_client = FakeClient()
|
|
old_client_ref = weakref.ref(old_client)
|
|
view._name = "camerad"
|
|
view._stream_type = object()
|
|
view.client = old_client
|
|
view.frame = None
|
|
view.available_streams = [object()]
|
|
view._target_client = FakeClient()
|
|
view._target_stream_type = object()
|
|
view._switching = True
|
|
view._texture_needs_update = False
|
|
view._regressive_frame_count = 2
|
|
view.last_connection_attempt = 123.0
|
|
view._closed = True
|
|
cleared = []
|
|
view._clear_textures = lambda: cleared.append(True)
|
|
|
|
del old_client
|
|
|
|
view._offroad_transition()
|
|
gc.collect()
|
|
|
|
assert old_client_ref() is None
|
|
assert cleared == [True]
|
|
assert view.frame is None
|
|
assert view.available_streams == []
|
|
assert view._target_client is None
|
|
assert view._target_stream_type is None
|
|
assert view._switching is False
|
|
assert view._texture_needs_update
|
|
assert view._regressive_frame_count == 0
|
|
assert view.last_connection_attempt == 0.0
|
|
|
|
|
|
def test_transition_callback_does_not_retain_camera_view(monkeypatch):
|
|
module = big_cameraview
|
|
|
|
class FakeClient:
|
|
pass
|
|
|
|
callbacks = []
|
|
monkeypatch.setattr(module, "TICI", False)
|
|
monkeypatch.setattr(module, "VisionIpcClient", lambda *_args, **_kwargs: FakeClient())
|
|
monkeypatch.setattr(module.rl, "load_shader_from_memory", lambda *_args: SimpleNamespace(id=1))
|
|
monkeypatch.setattr(module.rl, "get_shader_location", lambda *_args: 0)
|
|
monkeypatch.setattr(module.rl, "unload_shader", lambda *_args: None)
|
|
monkeypatch.setattr(module.ui_state, "add_offroad_transition_callback", callbacks.append)
|
|
monkeypatch.setattr(module.ui_state, "remove_offroad_transition_callback", callbacks.remove)
|
|
|
|
view = module.CameraView("camerad", object())
|
|
view_ref = weakref.ref(view)
|
|
assert len(callbacks) == 1
|
|
|
|
del view
|
|
gc.collect()
|
|
|
|
assert view_ref() is None
|
|
assert callbacks == []
|
|
|
|
|
|
def test_stream_switch_releases_graphics_before_old_client():
|
|
module = big_cameraview
|
|
|
|
events = []
|
|
|
|
class FakeClient:
|
|
pass
|
|
|
|
class FakeFrame:
|
|
pass
|
|
|
|
view = module.CameraView.__new__(module.CameraView)
|
|
old_client = FakeClient()
|
|
old_client_finalizer = weakref.finalize(old_client, events.append, "client")
|
|
old_frame = FakeFrame()
|
|
old_frame.frame_id = 10
|
|
old_frame.owner = old_client
|
|
old_frame_finalizer = weakref.finalize(old_frame, events.append, "frame")
|
|
view.client = old_client
|
|
view._target_client = FakeClient()
|
|
view._target_stream_type = object()
|
|
view._stream_type = object()
|
|
view._switching = True
|
|
view.frame = old_frame
|
|
view._regressive_frame_count = 2
|
|
view._texture_needs_update = False
|
|
view._closed = True
|
|
view._clear_textures = lambda: events.append("graphics")
|
|
view._initialize_textures = lambda: events.append("initialize")
|
|
del old_frame
|
|
del old_client
|
|
|
|
view._complete_switch(SimpleNamespace(frame_id=11))
|
|
gc.collect()
|
|
|
|
assert old_client_finalizer.alive is False
|
|
assert old_frame_finalizer.alive is False
|
|
assert events == ["graphics", "frame", "client", "initialize"]
|
|
assert view._regressive_frame_count == 0
|
|
|
|
|
|
def test_egl_cleanup_deletes_texture_before_images(monkeypatch):
|
|
module = big_cameraview
|
|
|
|
events = []
|
|
view = module.CameraView.__new__(module.CameraView)
|
|
view.texture_y = None
|
|
view.texture_uv = None
|
|
view.egl_texture = SimpleNamespace(id=7)
|
|
view._external_texture_id = 11
|
|
view.egl_images = {0: object(), 1: object()}
|
|
view._closed = True
|
|
|
|
view._use_egl = True
|
|
|
|
monkeypatch.setattr(module.rl, "unload_texture", lambda _texture: events.append("texture"))
|
|
monkeypatch.setattr(module, "destroy_external_texture", lambda _texture: events.append("external"))
|
|
monkeypatch.setattr(module, "destroy_egl_image", lambda _image: events.append("image"))
|
|
|
|
view._clear_textures()
|
|
|
|
assert events == ["external", "texture", "image", "image"]
|
|
assert view.egl_texture is None
|
|
assert view._external_texture_id == 0
|
|
assert view.egl_images == {}
|
|
|
|
|
|
def test_egl_cleanup_synchronizes_after_backend_switch(monkeypatch):
|
|
module = big_cameraview
|
|
|
|
events = []
|
|
view = module.CameraView.__new__(module.CameraView)
|
|
view.texture_y = None
|
|
view.texture_uv = None
|
|
view.egl_texture = SimpleNamespace(id=7)
|
|
view._external_texture_id = 11
|
|
view.egl_images = {0: object()}
|
|
view._use_egl = False
|
|
view._closed = True
|
|
|
|
monkeypatch.setattr(module, "is_egl_initialized", lambda: True)
|
|
monkeypatch.setattr(module.rl, "rl_draw_render_batch_active", lambda: events.append("flush"))
|
|
monkeypatch.setattr(module, "finish_gl", lambda: events.append("finish"))
|
|
monkeypatch.setattr(module.rl, "unload_texture", lambda _texture: events.append("texture"))
|
|
monkeypatch.setattr(module, "destroy_external_texture", lambda _texture: events.append("external"))
|
|
monkeypatch.setattr(module, "destroy_egl_image", lambda _image: events.append("image"))
|
|
|
|
view._clear_textures()
|
|
|
|
assert events == ["flush", "finish", "external", "texture", "image"]
|
|
|
|
|
|
def test_reverse_activation_cancels_mismatched_pending_switch():
|
|
view = mici_augmented_road_view.AugmentedRoadView.__new__(mici_augmented_road_view.AugmentedRoadView)
|
|
view._stream_type = mici_augmented_road_view.DRIVER_CAM
|
|
view._target_stream_type = mici_augmented_road_view.WIDE_CAM
|
|
view._target_client = object()
|
|
view._switching = True
|
|
view._closed = True
|
|
view._update_reverse_driver_camera_state = lambda: True
|
|
|
|
view._switch_stream_if_needed(None, mici_augmented_road_view.CAMERA_VIEW_AUTO)
|
|
|
|
assert view._target_client is None
|
|
assert view._target_stream_type is None
|
|
assert not view._switching
|
|
|
|
|
|
def test_onroad_reentry_keeps_matching_candidate_alive():
|
|
for module in (big_augmented_road_view, mici_augmented_road_view):
|
|
view = module.AugmentedRoadView.__new__(module.AugmentedRoadView)
|
|
candidate = object()
|
|
view._stream_type = module.ROAD_CAM
|
|
view._target_stream_type = module.ROAD_CAM
|
|
view._target_client = candidate
|
|
view._switching = True
|
|
view._onroad_reentry_pending = True
|
|
view._reentry_stream_selected = True
|
|
view.available_streams = [module.ROAD_CAM]
|
|
view._closed = True
|
|
view._update_reverse_driver_camera_state = lambda: False
|
|
view._refresh_available_streams = lambda: pytest.fail("reentry selection was repeated")
|
|
|
|
view._switch_stream_if_needed(None, module.CAMERA_VIEW_STANDARD)
|
|
|
|
assert view._target_client is candidate
|
|
assert view._target_stream_type == module.ROAD_CAM
|
|
assert view._switching
|
|
|
|
|
|
def test_onroad_transition_marks_camera_reentry(monkeypatch):
|
|
module = big_cameraview
|
|
|
|
class FakeClient:
|
|
pass
|
|
|
|
view = module.CameraView.__new__(module.CameraView)
|
|
view._name = "camerad"
|
|
view._stream_type = object()
|
|
view.client = FakeClient()
|
|
view.frame = None
|
|
view.available_streams = []
|
|
view._target_client = None
|
|
view._target_stream_type = None
|
|
view._switching = False
|
|
view._texture_needs_update = False
|
|
view._regressive_frame_count = 1
|
|
view._closed = True
|
|
view._onroad_reentry_pending = False
|
|
view._reentry_stream_selected = False
|
|
view._clear_textures = lambda: None
|
|
|
|
monkeypatch.setattr(module.ui_state, "is_onroad", lambda: True)
|
|
|
|
view._offroad_transition()
|
|
|
|
assert view._onroad_reentry_pending
|
|
assert not view._reentry_stream_selected
|