public unsafe static void ClosePaintElement(VisualElement ve, UIRStylePainter.ClosingInfo closingInfo, RenderChain renderChain, ref ChainBuilderStats stats) { if (closingInfo.clipperRegisterIndices.Length > 0) { NativeSlice <Vertex> verts = new NativeSlice <Vertex>(); NativeSlice <UInt16> indices = new NativeSlice <UInt16>(); UInt16 indexOffset = 0; // Due to device Update limitations, we cannot share the vertices of the registration mesh. It would be great // if we can just point winding-flipped indices towards the same vertices as the registration mesh. // For now, we duplicate the registration mesh entirely, wasting a bit of vertex memory UpdateOrAllocate(ref ve.renderChainData.closingData, closingInfo.clipperRegisterVertices.Length, closingInfo.clipperRegisterIndices.Length, renderChain.device, out verts, out indices, out indexOffset, ref stats); var job = new CopyClosingMeshJobData { vertSrc = (IntPtr)closingInfo.clipperRegisterVertices.GetUnsafePtr(), vertDst = (IntPtr)verts.GetUnsafePtr(), vertCount = verts.Length, indexSrc = (IntPtr)closingInfo.clipperRegisterIndices.GetUnsafePtr(), indexDst = (IntPtr)indices.GetUnsafePtr(), indexCount = indices.Length, indexOffset = indexOffset - closingInfo.clipperRegisterIndexOffset }; renderChain.jobManager.Add(ref job); closingInfo.clipUnregisterDrawCommand.mesh = ve.renderChainData.closingData; closingInfo.clipUnregisterDrawCommand.indexCount = indices.Length; } }
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); } }
internal void Reset() { bool disposed = this.disposed; if (disposed) { DisposeHelper.NotifyDisposedUsed(this); } else { this.ValidateMeshWriteData(); this.m_Entries.Clear(); this.m_VertsPool.SessionDone(); this.m_IndicesPool.SessionDone(); this.m_ClosingInfo = default(UIRStylePainter.ClosingInfo); this.m_NextMeshWriteDataPoolItem = 0; this.currentElement = null; this.totalVertices = (this.totalIndices = 0); } }