diag(explorer,fb0): vblank 返回等待迭代数并打点;脏行合并为一段渲染
排查'仍闪烁':① FB_WAIT_VBLANK 改为返回等待消耗的迭代数(到上限 = 超时 = 当前没有 VGA 回扫信号),explorer 首次调用打印一次 —— 用来判定垂直回扫同步是否真的生效;② render() 原来按连续脏行分段、每段各渲染一次,同一帧的多次写屏会跨越多个扫描周期,现在把脏行合并成一段连续范围一次性渲染,缩小撕裂窗口。
This commit is contained in:
1 parent
ecabd59518
commit
e1d31c3dc9
2 files changed
+25
-13
No files matched your search
@@ -11,6 +11,8 @@ import viperlib
|
||||
|
||||
# 【诊断·临时】首个鼠标包已收到的标记(0 = 未收到)
|
||||
_mouse_logged: int = 0
|
||||
# 首次 vblank 等待的迭代数只打一次(诊断同步是否真的生效;到上限 = 超时)
|
||||
_vblank_logged: int = 0
|
||||
|
||||
|
||||
# ============================================================================
|
||||
@@ -661,17 +663,26 @@ class DeskServer:
|
||||
|
||||
def render(self):
|
||||
if self.dirty_any == 0: return
|
||||
# 写屏前等垂直回扫(用户态不能 inb 0x3DA,由内核代等),避免撕裂
|
||||
devfs.fb_wait_vblank(self.fb_fd)
|
||||
y0: int = -1
|
||||
y1: int = -1
|
||||
y: int = 0
|
||||
while y < self.fb_h:
|
||||
if self.dirty[y] == 0:
|
||||
y += 1
|
||||
continue
|
||||
y0: int = y
|
||||
while y < self.fb_h and self.dirty[y] != 0:
|
||||
y += 1
|
||||
self.render_range(y0, y)
|
||||
if self.dirty[y] != 0:
|
||||
if y0 < 0: y0 = y
|
||||
y1 = y + 1
|
||||
y += 1
|
||||
if y0 < 0:
|
||||
self.clear_dirty()
|
||||
return
|
||||
# 写屏前等垂直回扫(用户态无 IO 权限,由内核代等);脏行合并成**一段**连续范围
|
||||
# 一次性渲染 —— 分段渲染会让同一帧的多次写屏跨越多个扫描周期,撕裂更明显。
|
||||
vw: int = devfs.fb_wait_vblank(self.fb_fd)
|
||||
if _vblank_logged == 0:
|
||||
_vblank_logged = 1
|
||||
_vb: [96]char
|
||||
viperlib.snprintf(&_vb, 96, "[explorer] vblank iters=%d\n", vw)
|
||||
devfs.serial_puts(&_vb)
|
||||
self.render_range(y0, y1)
|
||||
self.clear_dirty()
|
||||
|
||||
# ---------------- 事件投递 ----------------
|
||||
|
||||
@@ -522,12 +522,13 @@ virtual class framebuffer_device(devfs_file):
|
||||
|
||||
def ioctl(self, fd: int, request: int, arg: rawptr) -> int:
|
||||
if request == FB_WAIT_VBLANK:
|
||||
# 等进入垂直回扫期(0x3DA bit3)。带超时:当前若无 VGA 时序不至于死等。
|
||||
# 等进入垂直回扫期(0x3DA bit3)。返回等待消耗的迭代数:到上限即超时
|
||||
#(当前没有 VGA 回扫信号),调用方可据此判断同步是否真的生效。
|
||||
t: int = 100000
|
||||
while (asm.inb(0x3DA) & 0x08) != 0 and t > 0: t -= 1
|
||||
t = 100000
|
||||
while (asm.inb(0x3DA) & 0x08) == 0 and t > 0: t -= 1
|
||||
return 0
|
||||
t2: int = 100000
|
||||
while (asm.inb(0x3DA) & 0x08) == 0 and t2 > 0: t2 -= 1
|
||||
return 100000 - t2
|
||||
if request != FB_GET_INFO or not arg:
|
||||
return -1
|
||||
info: FbInfo* = FbInfo*(uint64(arg))
|
||||
|
||||
Reference in new issue
Block a user