static void DepthFirstOnVisualsChanged(RenderChain renderChain, VisualElement ve, uint dirtyID, bool parentHierarchyHidden, bool hierarchical, ref ChainBuilderStats stats) { if (dirtyID == ve.renderChainData.dirtyID) { return; } ve.renderChainData.dirtyID = dirtyID; // Prevent reprocessing of the same element in the same pass if (hierarchical) { stats.recursiveVisualUpdatesExpanded++; } bool wasHierarchyHidden = ve.renderChainData.isHierarchyHidden; ve.renderChainData.isHierarchyHidden = parentHierarchyHidden || IsElementHierarchyHidden(ve); if (wasHierarchyHidden != ve.renderChainData.isHierarchyHidden) { hierarchical = true; } if (!hierarchical && (ve.renderChainData.dirtiedValues & RenderDataDirtyTypes.AllVisuals) == RenderDataDirtyTypes.VisualsOpacityId) { stats.opacityIdUpdates++; CommandGenerator.UpdateOpacityId(ve, renderChain); return; } UpdateWorldFlipsWinding(ve); Debug.Assert(ve.renderChainData.clipMethod != ClipMethod.Undetermined); Debug.Assert(RenderChainVEData.AllocatesID(ve.renderChainData.transformID) || ve.hierarchy.parent == null || ve.renderChainData.transformID.Equals(ve.hierarchy.parent.renderChainData.transformID) || (ve.renderHints & RenderHints.GroupTransform) != 0); if (ve is TextElement) { RenderEvents.UpdateTextCoreSettings(renderChain, ve); } UIRStylePainter.ClosingInfo closingInfo = CommandGenerator.PaintElement(renderChain, ve, ref stats); if (hierarchical) { // Recurse on children int childrenCount = ve.hierarchy.childCount; for (int i = 0; i < childrenCount; i++) { DepthFirstOnVisualsChanged(renderChain, ve.hierarchy[i], dirtyID, ve.renderChainData.isHierarchyHidden, true, ref stats); } } // By closing the element after its children, we can ensure closing data is allocated // at a time that would maintain continuity in the index buffer if (closingInfo.needsClosing) { CommandGenerator.ClosePaintElement(ve, closingInfo, renderChain, ref stats); } }
static void OnColorChanged(RenderChain renderChain, VisualElement ve, uint dirtyID, ref ChainBuilderStats stats) { if (dirtyID == ve.renderChainData.dirtyID) { return; } ve.renderChainData.dirtyID = dirtyID; // Prevent reprocessing of the same element in the same pass stats.colorUpdatesExpanded++; var newColor = ve.resolvedStyle.backgroundColor; ve.renderChainData.backgroundColor = newColor; bool shouldUpdateVisuals = false; if ((ve.renderHints & RenderHints.DynamicColor) == RenderHints.DynamicColor) { if (InitColorIDs(renderChain, ve)) { // New colors were allocated, we need to update the visuals shouldUpdateVisuals = true; } SetColorValues(renderChain, ve); if (ve is TextElement && !RenderEvents.UpdateTextCoreSettings(renderChain, ve)) { shouldUpdateVisuals = true; } } else { shouldUpdateVisuals = true; } if (shouldUpdateVisuals) { renderChain.UIEOnVisualsChanged(ve, false); } }