跳到内容
CrossFly 是 100% 开源在 GitHub 关注我们
CrossFlyCrossFly
开始使用

本页面由葡萄牙语机器翻译,可能存在错误。葡萄牙语版本为准。

渲染管线

理解绘制如何变成像素,就能解释框架的多条性能规则。

Paint
高级门面
(rect, text, line, image)
局部坐标 + clip

gl / Renderers
每个图元一个渲染器
(每个都是一个 shader)

OpenGL

绘制的各个层次

  • 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
}

参见

这个页面有帮助吗?