参考:(五)UGUI源码分析之Rebuild(布局重建、图形重绘)
网格重建
网格重建大体包括布局重建和图形重建两部分。
public enum CanvasUpdate { Prelayout, Layout, PostLayout, PreRender, LatePreRender, MaxUpdateValue, }
@H_502_20@每一帧渲染前会进行触发Canvas.willRenderCanvases事件,CanvasUpdateRegistry单例注册PerformUpdate方法给事件。即:
每一帧渲染前会调用CanvasUpdateRegistry.PerformUpdate方法:
private void PerformUpdate() { UISystemProfilerApi.BeginSample(UISystemProfilerApi.SampleType.Layout); CleanInvalidItems(); m_PerformingLayoutUpdate = true; m_LayoutRebuildQueue.sort(s_SortLayoutFunction); for (int i = 0; i <= (int)CanvasUpdate.PostLayout; i++) { UnityEngine.Profiling.Profiler.BeginSample(m_CanvasUpdateProfilerStrings[i]); for (int j = 0; j < m_LayoutRebuildQueue.Count; j++) { var rebuild = instance.m_LayoutRebuildQueue[j]; try { if (ObjectValidForUpdate(rebuild)) rebuild.Rebuild((CanvasUpdate)i); } catch (Exception e) { Debug.LogException(e, rebuild.transform); } } UnityEngine.Profiling.Profiler.EndSample(); } for (int i = 0; i < m_LayoutRebuildQueue.Count; ++i) m_LayoutRebuildQueue[i].LayoutComplete(); instance.m_LayoutRebuildQueue.Clear(); m_PerformingLayoutUpdate = false; UISystemProfilerApi.EndSample(UISystemProfilerApi.SampleType.Layout); UISystemProfilerApi.BeginSample(UISystemProfilerApi.SampleType.Render); // Now layout is complete do culling... UnityEngine.Profiling.Profiler.BeginSample(m_CullingUpdateProfilerString); ClipperRegistry.instance.Cull(); UnityEngine.Profiling.Profiler.EndSample(); m_PerformingGraphicUpdate = true; for (var i = (int)CanvasUpdate.PreRender; i < (int)CanvasUpdate.MaxUpdateValue; i++) { UnityEngine.Profiling.Profiler.BeginSample(m_CanvasUpdateProfilerStrings[i]); for (var k = 0; k < instance.m_GraphicRebuildQueue.Count; k++) { try { var element = instance.m_GraphicRebuildQueue[k]; if (ObjectValidForUpdate(element)) element.Rebuild((CanvasUpdate)i); } catch (Exception e) { Debug.LogException(e, instance.m_GraphicRebuildQueue[k].transform); } } UnityEngine.Profiling.Profiler.EndSample(); } for (int i = 0; i < m_GraphicRebuildQueue.Count; ++i) m_GraphicRebuildQueue[i].GraphicUpdateComplete(); instance.m_GraphicRebuildQueue.Clear(); m_PerformingGraphicUpdate = false; UISystemProfilerApi.EndSample(UISystemProfilerApi.SampleType.Render); }
@H_502_20@
每一帧的网格重建流程:
布局重建
- Prelayout、Layout、PostLayout阶段各调用一遍布局重建列表(m_LayoutRebuildQueue)中各元素(ICanvasElement)的重建函数(Rebuild),即:将所有需要重新计算布局的元素进行Rebuild。所以,对接口ICanvasElement的Rebuild方法的实现里会对更新阶段进行判断,例如:if (executing == CanvasUpdate.Prelayout)。
- 布局重建完毕,调用各元素(ICanvasElement)的LayoutComplete()回调。
- 清空布局重建列表(m_LayoutRebuildQueue)。
图形重建
- 对所有已注册的IClipper执行裁剪:ClipperRegistry.instance.Cull();
- PreRender、LatePreRender、MaxUpdateValue阶段各调用一遍图形重建列表(m_GraphicRebuildQueue)中各元素(ICanvasElement)的重建函数(Rebuild),即:将所有需要重新绘制的元素进行Rebuild。
- 图形重建完毕,调用各元素(ICanvasElement)的GraphicUpdateComplete()回调。
- 清空图形重建列表(m_GraphicRebuildQueue)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。