Version History
date | version | Explanation | Author |
---|---|---|---|
2019-11-25 | 0.1 | The initial version of the document | Li Jun |
principle
- rebuild process
- Out correctly canvasrenderer mesh, material
- Graphic rebuild
- In the base class shown in Graphic ugui
- Image Pictures
- Text Text
RectTransform.widthGraphic.OnRectTransformDimensionsChangeGraphic.SetVerticesDirtyCanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuildCanvasUpdateRegistry.PerformUpdateGraphic.RebuildGraphic.UpdateGeometry&UpdateMaterialcanvasRenderer.SetMesh&SetMaterial&SetTexturegraph TB A[RectTransform.width] B[Graphic.OnRectTransformDimensionsChange] C[Graphic.SetVerticesDirty] D[CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild] E[CanvasUpdateRegistry.PerformUpdate] F[Graphic.Rebuild] G[Graphic.UpdateGeometry&UpdateMaterial] H[canvasRenderer.SetMesh&SetMaterial&SetTexture] A-->B B-->C C-->D D-->E E-->F F-->G G-->H
- Layout Rebuild
- computing sub-nodes recttransfrom
- ILayoutGroup layout Interface
- Base class layout LayoutGroup
- GridLayoutGroup grid layout
- HorizontalLayoutGroup horizontal layout
RectTransform.OnRectTransformDimensionsChangeLayoutGroup.SetDirtyLayoutRebuilder.MarkLayoutForRebuildLayoutRebuilder.MarkLayoutRootForRebuildCanvasUpdateRegistry.TryRegisterCanvasElementForLayoutRebuildLayoutRebuilder.RebuildILayoutElement.CalculateLayoutInputHorizontal & SetLayoutHorizontal & CalculateLayoutInputVertical & SetLayoutVerticalgraph TB [RectTransform.OnRectTransformDimensionsChange] B [LayoutGroup.SetDirty] C [LayoutRebuilder.MarkLayoutForRebuild] D [LayoutRebuilder.MarkLayoutRootForRebuild] E [CanvasUpdateRegistry.TryRegisterCanvasElementForLayoutRebuild] F [LayoutRebuilder. Rebuild] G [ILayoutElement.CalculateLayoutInputHorizontal & SetLayoutHorizontal & CalculateLayoutInputVertical & SetLayoutVertical] A -> B -> C -> D -> E -> F -> G
- Core code 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++) { 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); } } } for (int i = 0; i < m_LayoutRebuildQueue.Count; ++i) m_LayoutRebuildQueue[i].LayoutComplete(); instance.m_LayoutRebuildQueue.Clear(); m_PerformingLayoutUpdate = false; // now layout is complete do culling... ClipperRegistry.instance.Cull(); m_PerformingGraphicUpdate = true; for (var i = (int)CanvasUpdate.PreRender; i < (int)CanvasUpdate.MaxUpdateValue; 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); } } } for (int i = 0; i < m_GraphicRebuildQueue.Count; ++i) m_GraphicRebuildQueue[i].GraphicUpdateComplete(); instance.m_GraphicRebuildQueue.Clear(); m_PerformingGraphicUpdate = false; UISystemProfilerApi.EndSample(UISystemProfilerApi.SampleType.Layout); }
- The combined canvaserender batch process in the mesh, the process in the other thread, there is no source code, invisible
- Get all canvasrenderer according to hierarchy (depth-first)
- Bottom-up traversal List, and below the detection current renderer renderer intersection
- Do not intersect, depth = 0
- Intersect, in fact, the maximum depth of depthi, it is detected whether BATCH, can depth = depthi, not depth = depthi + 1
- All renderer based on their depth ordering, according to the same depth mat id, then according to the texture id
- If you can batch renderer adjacent to fit batch
ui production specification
- Principle rebuild> batch
- Reuild goal of reducing the number of times to reduce time-consuming rebuild reduce drawcall
- Separating movement in a different update frequency divided canvas fully static discharge element of a low-frequency synchronizing canvas high frequency in a high frequency sync canvas different in a canvas in the canvas
- As little as possible layout
- Atlas same, the same font (same size), as far as possible close to the hierarchy
- Do not be too deep hierarchy
Set up
-
canvas
-
image
-
text
ui deal with common situations
- Full-screen interface, where bad treatment tend to have more canvas
- More of the same element, it is recommended to hang auxiliary script, copy more awake in time
- This circular list with animation, proposes to add canvas on each item
- Props grid into several suggestions, do not use all of the most complete
- do not try to mask
index
- Often the main interface <40
- Full-screen interface <70
- Non-full-screen interface <30
faq
- Why not too much because node rebuild sorting, based on the number of the parent node