Performance Optimization -ui rebuild

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);  }
  1. The combined canvaserender batch process in the mesh, the process in the other thread, there is no source code, invisible
    1. Get all canvasrenderer according to hierarchy (depth-first)
    2. 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
    3. All renderer based on their depth ordering, according to the same depth mat id, then according to the texture id
    4. 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
  1. 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
  2. As little as possible layout
  3. Atlas same, the same font (same size), as far as possible close to the hierarchy
  4. Do not be too deep hierarchy

Set up

  • canvas

    • pixel perfect uncheck image
  • image

    • raycast tight background and buttons, input boxes image
  • text

    • rich text have overhead, try not
    • Do not use the best fit image

ui deal with common situations

  1. Full-screen interface, where bad treatment tend to have more canvas
  2. More of the same element, it is recommended to hang auxiliary script, copy more awake in time
  3. This circular list with animation, proposes to add canvas on each item
  4. Props grid into several suggestions, do not use all of the most complete
  5. 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

reference

https://blog.csdn.net/lingyun5905/article/details/84755092

Guess you like

Origin www.cnblogs.com/marcher/p/12161451.html