Add isolated fullscreen Mac showcase with native aspect ratio

This commit is contained in:
firestar5683
2026-09-20 11:38:06 -07:00
parent eeffb8ed62
commit fa8c0501b4
4 changed files with 141 additions and 0 deletions
+2
View File
@@ -387,6 +387,7 @@ def parser():
p.add_argument('--presentation-root',type=Path,help=argparse.SUPPRESS)
p.add_argument('--output-identity',help=argparse.SUPPRESS)
p.add_argument('--hold-start',action='store_true',help=argparse.SUPPRESS)
p.add_argument('--fullscreen',action='store_true',help='Show the native Mac UI fullscreen; F/F11 toggles, Escape returns to its window')
p.add_argument('--follow-playhead',action='store_true',help=argparse.SUPPRESS)
def paired_url(value):
try:GalaxyPeer(value,allow_lan_http=True)
@@ -440,6 +441,7 @@ def main():
env=os.environ.copy()
env.update(PYTHONDONTWRITEBYTECODE='1',ZMQ='1',OPENPILOT_ZMQ_NAMESPACE='roadscore-showcase-'+session,ROADSCORE_SHOWCASE_SESSION=session,ROADSCORE_PREPARED_SHOWCASE='1',ROADSCORE_REPLAY_UI_CONTROLS='1',PARAMS_ROOT=str(out/'params'),BASEDIR=str(rt),NOBOARD='1',SIMULATION='1',SKIP_FW_QUERY='1',BIG='0',SP_ALLOW_DESKTOP_FAKE_WIFI='0',SP_ALLOW_DESKTOP_FAKE_BLUETOOTH='0',SP_ONROAD_NAV_DEMO='0',SP_ONROAD_CEM_DEMO='0',ROADSCORE_CLEAN_DEMO_UI='1',ROADSCORE_OVERLAY='1',ROADSCORE_STATUS_FILE=str(out/'status.json'),ROADSCORE_UI_AUDIT=str(out/'ui_audit.jsonl'),ROADSCORE_OVERLAY_CAPTURE=str(out/'overlay.png'),ROADSCORE_PRESENTATION_POLICY='conservative-v4')
env['OPENPILOT_PREFIX']='roadscore-showcase-'+session
env['ROADSCORE_FULLSCREEN']='1' if a.fullscreen and not a.headless else '0'
env['ROADSCORE_AUDIO_DRAIN_FILE']=str(out/'audio_drained.json')
env['PWD']=str(rt)
env['PYTHONPATH']=':'.join(map(str,[HERE,rt,rt/'starpilot/third_party',*rt.glob('*_repo'),project/'roadscore/.analysis-venv/lib/python3.12/site-packages']))
+5
View File
@@ -77,4 +77,9 @@ def update(self,*args,**kw):
UIState.update=update;CameraView._accept_frame=accept;CameraView._render_textures=textures;ModelRenderer._draw_path=path;ModelRenderer._draw_lane_lines=lanes
from overlay import install
install()
if os.environ.get('ROADSCORE_FULLSCREEN')=='1':
from showcase_fullscreen import install as install_fullscreen
from openpilot.system.ui.lib.application import gui_app
import pyray as rl
install_fullscreen(rl,gui_app)
runpy.run_path(str(Path(os.environ['BASEDIR'])/'selfdrive/ui/ui.py'),run_name='__main__')
@@ -0,0 +1,80 @@
"""Opt-in desktop presentation of the unchanged native canvas, with letterboxing."""
import os
import sys
def viewport(width, height, canvas_width, canvas_height):
scale=min(width/canvas_width,height/canvas_height)
return ((width-canvas_width*scale)/2,(height-canvas_height*scale)/2,
canvas_width*scale,canvas_height*scale)
class FullscreenCanvas:
def __init__(self, rl, app):
self.rl,self.app=rl,app
self.base_scale=app._scale
self.rect=(0.,0.,float(app._scaled_width),float(app._scaled_height))
self.size=None
def toggle(self):
self.rl.toggle_borderless_windowed()
def update(self):
rl,app=self.rl,self.app
if rl.is_key_pressed(rl.KeyboardKey.KEY_F11) or rl.is_key_pressed(rl.KeyboardKey.KEY_F):self.toggle()
elif rl.is_key_pressed(rl.KeyboardKey.KEY_ESCAPE) and rl.is_window_state(rl.ConfigFlags.FLAG_BORDERLESS_WINDOWED_MODE):self.toggle()
width,height=max(1,rl.get_screen_width()),max(1,rl.get_screen_height())
size=(width,height,max(1,rl.get_render_width()),max(1,rl.get_render_height()))
if size==self.size:return
self.size=size
self.rect=viewport(width,height,app.width,app.height)
pixel_width=max(1,round(self.rect[2]*size[2]/width))
pixel_height=max(1,round(self.rect[3]*size[3]/height))
if app._render_texture is not None:rl.unload_render_texture(app._render_texture)
app._render_texture=rl.load_render_texture(pixel_width,pixel_height)
rl.set_texture_filter(app._render_texture.texture,rl.TextureFilter.TEXTURE_FILTER_BILINEAR)
app._render_texture_width,app._render_texture_height=pixel_width,pixel_height
app._pixel_scale_x=pixel_width/(app.width*app._scale)
app._pixel_scale_y=pixel_height/(app.height*app._scale)
app._patch_scissor_mode()
def map_event(self, event):
x,y,width,height=self.rect
position=event.pos
mapped=type(position)((position.x*self.base_scale-x)*self.app.width/width,
(position.y*self.base_scale-y)*self.app.height/height)
return event._replace(pos=mapped)
def install(rl, app, *, environ=None, platform=None):
env=os.environ if environ is None else environ
if ((sys.platform if platform is None else platform)!='darwin'
or env.get('ROADSCORE_FULLSCREEN')!='1' or env.get('ROADSCORE_PREPARED_SHOWCASE')!='1'
or env.get('SIMULATION')!='1' or env.get('BIG','0')!='0'):
return False
original_init=app.init_window
original_progress=app._mark_progress
original_draw=rl.draw_texture_pro
original_events=app._mouse.get_events
canvas=FullscreenCanvas(rl,app)
def init_window(*args,**kwargs):
result=original_init(*args,**kwargs)
rl.set_exit_key(rl.KeyboardKey.KEY_NULL)
canvas.toggle()
canvas.update()
return result
def progress(label):
# Before mouse collection and render-target binding, never during drawing.
if label=='gui_app.loop_start':canvas.update()
return original_progress(label)
def draw(texture,source,destination,origin,rotation,tint):
if app._render_texture is not None and texture.id==app._render_texture.texture.id:
destination=rl.Rectangle(*canvas.rect)
return original_draw(texture,source,destination,origin,rotation,tint)
def events():return [canvas.map_event(event) for event in original_events()]
app.init_window=init_window
app._mark_progress=progress
app._mouse.get_events=events
rl.draw_texture_pro=draw
app._roadscore_fullscreen=canvas
return True
@@ -0,0 +1,54 @@
from collections import namedtuple
from types import SimpleNamespace
import unittest
from mac_showcase import parser
from showcase_fullscreen import FullscreenCanvas, install, viewport
class FullscreenTests(unittest.TestCase):
def test_aspect_and_center_preserved_on_wide_and_tall_monitors(self):
for width,height in ((1440,900),(1920,1080),(2560,1080),(900,1440)):
x,y,w,h=viewport(width,height,536,240)
self.assertAlmostEqual(w/h,536/240)
self.assertAlmostEqual(x*2+w,width);self.assertAlmostEqual(y*2+h,height)
self.assertGreaterEqual(x,0);self.assertGreaterEqual(y,0)
self.assertLessEqual(w,width);self.assertLessEqual(h,height)
def test_pointer_maps_canvas_corners_and_letterbox_stays_outside(self):
app=SimpleNamespace(_scale=1.,_scaled_width=536,_scaled_height=240,width=536,height=240)
canvas=FullscreenCanvas(None,app);canvas.rect=viewport(1440,900,536,240)
Pos=namedtuple('Pos','x y');Event=namedtuple('Event','pos')
x,y,w,h=canvas.rect
self.assertEqual(canvas.map_event(Event(Pos(x,y))).pos,Pos(0.,0.))
corner=canvas.map_event(Event(Pos(x+w,y+h))).pos
self.assertAlmostEqual(corner.x,536.);self.assertAlmostEqual(corner.y,240.)
self.assertLess(canvas.map_event(Event(Pos(0,0))).pos.y,0)
def test_flag_defaults_and_device_gates(self):
self.assertFalse(parser().parse_args([]).fullscreen)
self.assertTrue(parser().parse_args(['--fullscreen']).fullscreen)
env=dict(ROADSCORE_FULLSCREEN='1',ROADSCORE_PREPARED_SHOWCASE='1',SIMULATION='1',BIG='0')
self.assertFalse(install(None,None,environ=env,platform='linux'))
for patch in ({'ROADSCORE_FULLSCREEN':'0'},{'SIMULATION':'0'},{'BIG':'1'},{'ROADSCORE_PREPARED_SHOWCASE':'0'}):
self.assertFalse(install(None,None,environ=env|patch,platform='darwin'))
def test_resize_reallocates_canvas_and_escape_toggles_without_close(self):
allocations=[];keys=set();toggles=[]
rl=SimpleNamespace(KeyboardKey=SimpleNamespace(KEY_F11=11,KEY_F=70,KEY_ESCAPE=27),
ConfigFlags=SimpleNamespace(FLAG_BORDERLESS_WINDOWED_MODE=1),
TextureFilter=SimpleNamespace(TEXTURE_FILTER_BILINEAR=1),
is_key_pressed=lambda key:key in keys,is_window_state=lambda flag:True,
toggle_borderless_windowed=lambda:toggles.append(True),get_screen_width=lambda:1440,get_screen_height=lambda:900,
get_render_width=lambda:2880,get_render_height=lambda:1800,unload_render_texture=lambda texture:None,
load_render_texture=lambda w,h:allocations.append((w,h)) or SimpleNamespace(texture=1),set_texture_filter=lambda *args:None)
app=SimpleNamespace(_scale=1.,_scaled_width=536,_scaled_height=240,width=536,height=240,
_render_texture=None,_patch_scissor_mode=lambda:None)
canvas=FullscreenCanvas(rl,app);canvas.update();canvas.update()
self.assertEqual(len(allocations),1)
self.assertEqual(allocations[0][0],2880)
self.assertAlmostEqual(app._pixel_scale_x,2880/536)
keys.add(27);canvas.update();self.assertEqual(len(toggles),1)
if __name__=='__main__':unittest.main()