perf(explorer): 背景只铺窗口外区间;进主循环前整屏刷一次

① 修卡:render_range 原来对每一行都先铺整行背景(全宽)再画窗口,对窗口覆盖的那几百列纯属浪费 —— Scene3D 每帧刷全窗时等于每帧多拷一整屏背景。改为逐行只铺没被任何可见窗口覆盖的 x 区间(窗口收集与 z 排序提到背景之前)。② 修 VGA 残留:内核启动期的 VGA/gfx 测试内容(蓝色测试块)不属于任何脏行,只靠增量渲染会永远留在屏幕上;serve() 进主循环前先 mark_all + 整屏渲染一次。
This commit is contained in:
TermiNexus committed 2026-10-16 23:07:09 +08:00
1 parent 78b0ca8db7
commit ae39fab5d8
1 file changed
+23 -6
+23 -6
View File
@@ -767,12 +767,7 @@ class DeskServer:
# ---------------- 渲染 ----------------
def render_range(self, y0: int, y1: int):
# 1) 背景
for yy in range(y0, y1):
self.row_blit(0, yy, self.bg_row, 0, self.fb_w)
# 2) 任务栏(先于窗口,窗口会盖住它 —— 与内核桌面同序)
self._draw_taskbar_rows(y0, y1)
# 3) 窗口按 Z 序升序(选择排序,窗口数 ≤ 8)
# 窗口按 Z 序升序(选择排序,窗口数 ≤ 8)—— 背景裁剪与窗口绘制都要用
order: [desk.DESK_MAX_WIN]int
cnt: int = 0
for i in range(desk.DESK_MAX_WIN):
@@ -788,6 +783,24 @@ class DeskServer:
t: int = order[a]
order[a] = order[b]
order[b] = t
# 1) 背景:只铺"没有被窗口覆盖"的 x 区间。整行铺背景对窗口完全覆盖的那几百列是纯浪费
# (Scene3D 每帧刷全窗,等于每帧多拷一整屏背景)。
yy: int = y0
while yy < y1:
xx: int = 0
for i in range(cnt):
s: desk.WinSlot* = self.slot(order[i])
if yy < s.uy or yy >= s.uy + s.h: continue
if s.ux > xx:
self.row_blit(xx, yy, self.bg_row, xx, s.ux - xx)
ex: int = s.ux + s.w
if ex > xx: xx = ex
if xx < self.fb_w:
self.row_blit(xx, yy, self.bg_row, xx, self.fb_w - xx)
yy += 1
# 2) 任务栏(先于窗口,窗口会盖住它 —— 与内核桌面同序)
self._draw_taskbar_rows(y0, y1)
# 3) 窗口
for i in range(cnt):
self.render_window_rows(order[i], y0, y1)
# 4) 光标
@@ -1174,6 +1187,10 @@ class DeskServer:
# ---------------- 主循环 ----------------
def serve(self):
# 进主循环前先整屏刷一次:内核启动期的 VGA/gfx 测试内容(例如蓝色测试块)不在任何
# 脏行里,只靠后续增量渲染会永远留在屏幕上。
self.mark_all()
self.render()
while True:
self.poll_requests()
self.poll_input()