本页面由葡萄牙语机器翻译,可能存在错误。葡萄牙语版本为准。
渲染管线
理解绘制如何变成像素,就能解释框架的多条性能规则。
绘制的各个层次
Paint是你在onPaint(...)中用来绘制的门面。它以本地坐标、 clip 和平移来思考 —— 并且完全不了解 shader 或 OpenGL。你说“在这里 画这个矩形”;至于它如何变成三角形和 GPU 调用,那不是你要操心的。gl/ 渲染器 —— 每种图元都有一个专用渲染器(矩形、圆角 矩形、线、文本、图像……),每一个本质上都是一个 shader。Paint把工作委派给 正确的渲染器。- OpenGL —— 最终的 draw calls。
核心概念:batching
渲染器会把同一类型的绘制批量(batch)在一起,以减少 GPU 调用。由此 推导出一条规则:
切换图元类型会“关闭”前一个 batch。 绘制顺序始终被保留,但 交替类型(矩形 → 文本 → 矩形 → 文本)会强制多次 flush;把同一类型的调用 归拢在一起才是带来性能的关键。
实践中,在繁重的自定义绘制里,把所有矩形一起画完再画所有文本,比交替 绘制的性能更好。
按需渲染 + 整树重绘
渲染模型的两个特性会影响你编写 onPaint 的方式:
- 按需: 屏幕只有在有人请求时才重绘(
repaint()→requestRendering())。没有 请求,就不会生成新帧 —— 这能省电。(其线程相关的视角见 paint thread。) - 没有脏矩形: 当一帧发生时,整个可见树都会被重绘,而不只是 改变的那部分。不存在局部重绘。
其实际后果是一条原则:
让
onPaint保持廉价。 它在每个渲染帧都会对整棵树运行一遍 —— 不要在其中 分配对象、加载资源或做昂贵计算。
一帧如何组装(高层视角)
在每个渲染帧,EventsProcessor 绘制窗口栈(通过 paintWindows(...)):栈顶
窗口在上,下方窗口在后(弹窗会让前一个窗口仍然可见)。每个可见组件
都会收到它的 onPaint(Paint)。
// onPaint 最小且廉价:复用临时对象,在本地坐标中绘制(0,0 = 左上角)
@Override public void onPaint(Paint paint) throws Exception {
paint.rect(scratch.bounds(0, 0, width, height).fill(bg)); // 'scratch' 是一个可复用的 GRect
}
参见
- 应用:自定义绘制
- 下一篇:paint thread
这个页面有帮助吗?感谢你的反馈!