Пример #1
0
        public void Render(Rect topRect, Matrix4x4 projection)
        {
            s_RenderSampler.Begin();
            m_Stats = new ChainBuilderStats();
            m_Stats.elementsAdded        += m_StatsElementsAdded;
            m_Stats.elementsRemoved      += m_StatsElementsRemoved;
            m_Stats.clipListCleanup      += m_StatsClipListCleanup;
            m_Stats.transformListCleanup += m_StatsTransformListCleanup;
            m_Stats.visualListCleanup    += m_StatsVisualListCleanup;
            m_StatsElementsAdded          = m_StatsElementsRemoved = 0;
            m_StatsClipListCleanup        = m_StatsTransformListCleanup = m_StatsVisualListCleanup = 0;

            if (atlasManager?.RequiresReset() == true)
            {
                atlasManager.Reset(); // May cause a dirty repaint
            }
            m_DirtyID++;
            var           clearDirty = ~(RenderDataDirtyTypes.Clipping | RenderDataDirtyTypes.ClippingHierarchy);
            VisualElement dirty      = m_FirstDirtyClipping;

            s_ClipProcessingSampler.Begin();
            while (dirty != null)
            {
                if (dirty.renderChainData.isInChain && dirty.renderChainData.dirtyID != m_DirtyID)
                {
                    Implementation.RenderEvents.ProcessOnClippingChanged(this, dirty, m_DirtyID, device, ref m_Stats);
                }
                dirty.renderChainData.dirtiedValues &= clearDirty;
                var old = dirty;
                dirty = dirty.renderChainData.nextDirtyClipping;
                old.renderChainData.nextDirtyClipping = null;
            }
            s_ClipProcessingSampler.End();
            m_FirstDirtyClipping = m_LastDirtyClipping = null;

            m_DirtyID++;
            clearDirty = ~(RenderDataDirtyTypes.Transform | RenderDataDirtyTypes.Size);
            dirty      = m_FirstDirtyTransformOrSize;
            s_TransformProcessingSampler.Begin();
            while (dirty != null)
            {
                if (dirty.renderChainData.isInChain && dirty.renderChainData.dirtyID != m_DirtyID)
                {
                    Implementation.RenderEvents.ProcessOnTransformOrSizeChanged(this, dirty, m_DirtyID, device, ref m_Stats);
                }
                dirty.renderChainData.dirtiedValues &= clearDirty;
                var old = dirty;
                dirty = dirty.renderChainData.nextDirtyTransformOrSize;
                old.renderChainData.nextDirtyTransformOrSize = null;
            }
            s_TransformProcessingSampler.End();
            m_FirstDirtyTransformOrSize = m_LastDirtyTransformOrSize = null;

            m_DirtyID++;
            clearDirty = ~(RenderDataDirtyTypes.Visuals | RenderDataDirtyTypes.VisualsHierarchy);
            dirty      = m_FirstDirtyVisuals;
            s_VisualsProcessingSampler.Begin();
            while (dirty != null)
            {
                if (dirty.renderChainData.isInChain && dirty.renderChainData.dirtyID != m_DirtyID)
                {
                    Implementation.RenderEvents.ProcessOnVisualsChanged(this, dirty, m_DirtyID, ref m_Stats);
                }
                dirty.renderChainData.dirtiedValues &= clearDirty;
                var old = dirty;
                dirty = dirty.renderChainData.nextDirtyVisuals;
                old.renderChainData.nextDirtyVisuals = null;
            }
            s_VisualsProcessingSampler.End();
            m_FirstDirtyVisuals = m_LastDirtyVisuals = null;

            ProcessTextRegen(true);

            if (m_FontWasReset)
            {
                // We regenerate the text when the font texture was reset since we don't have any guarantees
                // the the glyphs are going to end up at the same spot in the texture.
                // Up to two passes may be necessary with time-slicing turned off to fully update the text.
                const int kMaxTextPasses = 2;
                for (int i = 0; i < kMaxTextPasses; ++i)
                {
                    if (!m_FontWasReset)
                    {
                        break;
                    }
                    m_FontWasReset = false;
                    ProcessTextRegen(false);
                }
            }


            atlasManager?.Update(); // Commit new requests if any

            if (BeforeDrawChain != null)
            {
                BeforeDrawChain(device);
            }

            Exception immediateException = null;

            device.DrawChain(m_FirstCommand, topRect, projection, atlasManager?.atlas, ref immediateException);

            s_RenderSampler.End();

            if (immediateException != null)
            {
                throw immediateException;
            }

            if (drawStats)
            {
                DrawStats();
            }
        }
Пример #2
0
        public void ProcessChanges()
        {
            s_MarkerProcess.Begin();
            m_Stats = new ChainBuilderStats();
            m_Stats.elementsAdded   += m_StatsElementsAdded;
            m_Stats.elementsRemoved += m_StatsElementsRemoved;
            m_StatsElementsAdded     = m_StatsElementsRemoved = 0;

            if (shaderInfoAllocator.isReleased)
            {
                RecreateDevice(); // The shader info texture was released, recreate the device to start fresh
            }
            if (m_DrawInCameras && m_StaticIndex < 0)
            {
                m_StaticIndex = RenderChainStaticIndexAllocator.AllocateIndex(this);
            }
            else if (!m_DrawInCameras && m_StaticIndex >= 0)
            {
                RenderChainStaticIndexAllocator.FreeIndex(m_StaticIndex);
                m_StaticIndex = -1;
            }

            if (OnPreRender != null)
            {
                OnPreRender();
            }

            bool atlasWasReset = false;

            if (atlasManager?.RequiresReset() == true)
            {
                atlasManager.Reset(); // May cause a dirty repaint
                atlasWasReset = true;
            }
            if (vectorImageManager?.RequiresReset() == true)
            {
                vectorImageManager.Reset();
                atlasWasReset = true;
            }
            // Although shaderInfoAllocator uses an atlas internally, it doesn't need to
            // reset it due to any of the current reasons that the atlas is reset for, thus we don't do it.

            if (atlasWasReset)
            {
                RepaintAtlassedElements();
            }


            int dirtyClass;
            RenderDataDirtyTypes dirtyFlags;
            RenderDataDirtyTypes clearDirty;

            m_DirtyTracker.dirtyID++;
            dirtyClass = (int)RenderDataDirtyTypeClasses.Clipping;
            dirtyFlags = RenderDataDirtyTypes.Clipping | RenderDataDirtyTypes.ClippingHierarchy;
            clearDirty = ~dirtyFlags;
            s_MarkerClipProcessing.Begin();
            for (int depth = m_DirtyTracker.minDepths[dirtyClass]; depth <= m_DirtyTracker.maxDepths[dirtyClass]; depth++)
            {
                VisualElement ve = m_DirtyTracker.heads[depth];
                while (ve != null)
                {
                    VisualElement veNext = ve.renderChainData.nextDirty;
                    if ((ve.renderChainData.dirtiedValues & dirtyFlags) != 0)
                    {
                        if (ve.renderChainData.isInChain && ve.renderChainData.dirtyID != m_DirtyTracker.dirtyID)
                        {
                            Implementation.RenderEvents.ProcessOnClippingChanged(this, ve, m_DirtyTracker.dirtyID,
                                                                                 ref m_Stats);
                        }
                        m_DirtyTracker.ClearDirty(ve, clearDirty);
                    }
                    ve = veNext;
                    m_Stats.dirtyProcessed++;
                }
            }
            s_MarkerClipProcessing.End();

            m_DirtyTracker.dirtyID++;
            dirtyClass = (int)RenderDataDirtyTypeClasses.Opacity;
            dirtyFlags = RenderDataDirtyTypes.Opacity;
            clearDirty = ~dirtyFlags;
            s_MarkerOpacityProcessing.Begin();
            for (int depth = m_DirtyTracker.minDepths[dirtyClass]; depth <= m_DirtyTracker.maxDepths[dirtyClass]; depth++)
            {
                VisualElement ve = m_DirtyTracker.heads[depth];
                while (ve != null)
                {
                    VisualElement veNext = ve.renderChainData.nextDirty;
                    if ((ve.renderChainData.dirtiedValues & dirtyFlags) != 0)
                    {
                        if (ve.renderChainData.isInChain && ve.renderChainData.dirtyID != m_DirtyTracker.dirtyID)
                        {
                            Implementation.RenderEvents.ProcessOnOpacityChanged(this, ve, m_DirtyTracker.dirtyID, ref m_Stats);
                        }
                        m_DirtyTracker.ClearDirty(ve, clearDirty);
                    }
                    ve = veNext;
                    m_Stats.dirtyProcessed++;
                }
            }
            s_MarkerOpacityProcessing.End();

            m_DirtyTracker.dirtyID++;
            dirtyClass = (int)RenderDataDirtyTypeClasses.TransformSize;
            dirtyFlags = RenderDataDirtyTypes.Transform | RenderDataDirtyTypes.ClipRectSize;
            clearDirty = ~dirtyFlags;
            s_MarkerTransformProcessing.Begin();
            for (int depth = m_DirtyTracker.minDepths[dirtyClass]; depth <= m_DirtyTracker.maxDepths[dirtyClass]; depth++)
            {
                VisualElement ve = m_DirtyTracker.heads[depth];
                while (ve != null)
                {
                    VisualElement veNext = ve.renderChainData.nextDirty;
                    if ((ve.renderChainData.dirtiedValues & dirtyFlags) != 0)
                    {
                        if (ve.renderChainData.isInChain && ve.renderChainData.dirtyID != m_DirtyTracker.dirtyID)
                        {
                            Implementation.RenderEvents.ProcessOnTransformOrSizeChanged(this, ve, m_DirtyTracker.dirtyID, ref m_Stats);
                        }
                        m_DirtyTracker.ClearDirty(ve, clearDirty);
                    }
                    ve = veNext;
                    m_Stats.dirtyProcessed++;
                }
            }
            s_MarkerTransformProcessing.End();

            m_BlockDirtyRegistration = true; // Processing visuals may call generateVisualContent, which must be restricted to the allowed operations
            m_DirtyTracker.dirtyID++;
            dirtyClass = (int)RenderDataDirtyTypeClasses.Visuals;
            dirtyFlags = RenderDataDirtyTypes.Visuals | RenderDataDirtyTypes.VisualsHierarchy;
            clearDirty = ~dirtyFlags;
            s_MarkerVisualsProcessing.Begin();
            for (int depth = m_DirtyTracker.minDepths[dirtyClass]; depth <= m_DirtyTracker.maxDepths[dirtyClass]; depth++)
            {
                VisualElement ve = m_DirtyTracker.heads[depth];
                while (ve != null)
                {
                    VisualElement veNext = ve.renderChainData.nextDirty;
                    if ((ve.renderChainData.dirtiedValues & dirtyFlags) != 0)
                    {
                        if (ve.renderChainData.isInChain && ve.renderChainData.dirtyID != m_DirtyTracker.dirtyID)
                        {
                            Implementation.RenderEvents.ProcessOnVisualsChanged(this, ve, m_DirtyTracker.dirtyID, ref m_Stats);
                        }
                        m_DirtyTracker.ClearDirty(ve, clearDirty);
                    }
                    ve = veNext;
                    m_Stats.dirtyProcessed++;
                }
            }
            s_MarkerVisualsProcessing.End();
            m_BlockDirtyRegistration = false;

            // Done with all dirtied elements
            m_DirtyTracker.Reset();

            ProcessTextRegen(true);

            if (m_FontWasReset)
            {
                // We regenerate the text when the font texture was reset since we don't have any guarantees
                // the the glyphs are going to end up at the same spot in the texture.
                // Up to two passes may be necessary with time-slicing turned off to fully update the text.
                const int kMaxTextPasses = 2;
                for (int i = 0; i < kMaxTextPasses; ++i)
                {
                    if (!m_FontWasReset)
                    {
                        break;
                    }
                    m_FontWasReset = false;
                    ProcessTextRegen(false);
                }
            }


            // Commit new requests for atlases if any
            atlasManager?.Commit();
            vectorImageManager?.Commit();
            shaderInfoAllocator.IssuePendingAtlasBlits();

            device?.OnFrameRenderingBegin();

            s_MarkerProcess.End();
        }
Пример #3
0
        public void Render(Rect viewport, Matrix4x4 projection)
        {
            s_RenderSampler.Begin();
            m_Stats = new ChainBuilderStats();
            m_Stats.elementsAdded   += m_StatsElementsAdded;
            m_Stats.elementsRemoved += m_StatsElementsRemoved;
            m_StatsElementsAdded     = m_StatsElementsRemoved = 0;

            if (OnPreRender != null)
            {
                OnPreRender();
            }

            bool atlasWasReset = false;

            if (atlasManager?.RequiresReset() == true)
            {
                atlasManager.Reset(); // May cause a dirty repaint
                atlasWasReset = true;
            }
            if (vectorImageManager?.RequiresReset() == true)
            {
                vectorImageManager.Reset();
                atlasWasReset = true;
            }

            if (atlasWasReset)
            {
                RepaintAtlassedElements();
            }


            m_DirtyTracker.dirtyID++;
            var dirtyClass = (int)RenderDataDirtyTypeClasses.Clipping;
            var dirtyFlags = RenderDataDirtyTypes.Clipping | RenderDataDirtyTypes.ClippingHierarchy;
            var clearDirty = ~dirtyFlags;

            s_ClipProcessingSampler.Begin();
            for (int depth = m_DirtyTracker.minDepths[dirtyClass]; depth <= m_DirtyTracker.maxDepths[dirtyClass]; depth++)
            {
                VisualElement ve = m_DirtyTracker.heads[depth];
                while (ve != null)
                {
                    VisualElement veNext = ve.renderChainData.nextDirty;
                    if ((ve.renderChainData.dirtiedValues & dirtyFlags) != 0)
                    {
                        if (ve.renderChainData.isInChain && ve.renderChainData.dirtyID != m_DirtyTracker.dirtyID)
                        {
                            Implementation.RenderEvents.ProcessOnClippingChanged(this, ve, m_DirtyTracker.dirtyID, device, ref m_Stats);
                        }
                        m_DirtyTracker.ClearDirty(ve, clearDirty);
                    }
                    ve = veNext;
                }
            }
            s_ClipProcessingSampler.End();

            m_DirtyTracker.dirtyID++;
            dirtyClass = (int)RenderDataDirtyTypeClasses.Opacity;
            dirtyFlags = RenderDataDirtyTypes.Opacity;
            clearDirty = ~dirtyFlags;
            s_OpacityProcessingSampler.Begin();
            for (int depth = m_DirtyTracker.minDepths[dirtyClass]; depth <= m_DirtyTracker.maxDepths[dirtyClass]; depth++)
            {
                VisualElement ve = m_DirtyTracker.heads[depth];
                while (ve != null)
                {
                    VisualElement veNext = ve.renderChainData.nextDirty;
                    if ((ve.renderChainData.dirtiedValues & dirtyFlags) != 0)
                    {
                        if (ve.renderChainData.isInChain && ve.renderChainData.dirtyID != m_DirtyTracker.dirtyID)
                        {
                            Implementation.RenderEvents.ProcessOnOpacityChanged(this, ve, m_DirtyTracker.dirtyID, ref m_Stats);
                        }
                        m_DirtyTracker.ClearDirty(ve, clearDirty);
                    }
                    ve = veNext;
                }
            }
            s_OpacityProcessingSampler.End();

            m_DirtyTracker.dirtyID++;
            dirtyClass = (int)RenderDataDirtyTypeClasses.TransformSize;
            dirtyFlags = RenderDataDirtyTypes.Transform | RenderDataDirtyTypes.Size;
            clearDirty = ~dirtyFlags;
            s_TransformProcessingSampler.Begin();
            for (int depth = m_DirtyTracker.minDepths[dirtyClass]; depth <= m_DirtyTracker.maxDepths[dirtyClass]; depth++)
            {
                VisualElement ve = m_DirtyTracker.heads[depth];
                while (ve != null)
                {
                    VisualElement veNext = ve.renderChainData.nextDirty;
                    if ((ve.renderChainData.dirtiedValues & dirtyFlags) != 0)
                    {
                        if (ve.renderChainData.isInChain && ve.renderChainData.dirtyID != m_DirtyTracker.dirtyID)
                        {
                            Implementation.RenderEvents.ProcessOnTransformOrSizeChanged(this, ve, m_DirtyTracker.dirtyID, device, ref m_Stats);
                        }
                        m_DirtyTracker.ClearDirty(ve, clearDirty);
                    }
                    ve = veNext;
                }
            }
            s_TransformProcessingSampler.End();

            m_BlockDirtyRegistration = true; // Processing visuals may call generateVisualContent, which must be restricted to the allowed operations
            m_DirtyTracker.dirtyID++;
            dirtyClass = (int)RenderDataDirtyTypeClasses.Visuals;
            dirtyFlags = RenderDataDirtyTypes.Visuals | RenderDataDirtyTypes.VisualsHierarchy;
            clearDirty = ~dirtyFlags;
            s_VisualsProcessingSampler.Begin();
            for (int depth = m_DirtyTracker.minDepths[dirtyClass]; depth <= m_DirtyTracker.maxDepths[dirtyClass]; depth++)
            {
                VisualElement ve = m_DirtyTracker.heads[depth];
                while (ve != null)
                {
                    VisualElement veNext = ve.renderChainData.nextDirty;
                    if ((ve.renderChainData.dirtiedValues & dirtyFlags) != 0)
                    {
                        if (ve.renderChainData.isInChain && ve.renderChainData.dirtyID != m_DirtyTracker.dirtyID)
                        {
                            Implementation.RenderEvents.ProcessOnVisualsChanged(this, ve, m_DirtyTracker.dirtyID, ref m_Stats);
                        }
                        m_DirtyTracker.ClearDirty(ve, clearDirty);
                    }
                    ve = veNext;
                }
            }
            s_VisualsProcessingSampler.End();
            m_BlockDirtyRegistration = false;

            // Done with all dirtied elements
            m_DirtyTracker.Reset();

            ProcessTextRegen(true);

            if (m_FontWasReset)
            {
                // We regenerate the text when the font texture was reset since we don't have any guarantees
                // the the glyphs are going to end up at the same spot in the texture.
                // Up to two passes may be necessary with time-slicing turned off to fully update the text.
                const int kMaxTextPasses = 2;
                for (int i = 0; i < kMaxTextPasses; ++i)
                {
                    if (!m_FontWasReset)
                    {
                        break;
                    }
                    m_FontWasReset = false;
                    ProcessTextRegen(false);
                }
            }


            // Commit new requests for atlases if any
            atlasManager?.Commit();
            vectorImageManager?.Commit();

            if (BeforeDrawChain != null)
            {
                BeforeDrawChain(device);
            }

            Exception immediateException = null;

            device.DrawChain(m_FirstCommand, viewport, projection, atlasManager?.atlas, vectorImageManager?.atlas, (panel as BaseVisualElementPanel).scaledPixelsPerPoint, ref immediateException);

            s_RenderSampler.End();

            if (immediateException != null)
            {
                throw immediateException;
            }

            if (drawStats)
            {
                DrawStats();
            }
        }
Пример #4
0
        public void ProcessChanges()
        {
            s_MarkerProcess.Begin();
            m_Stats = new ChainBuilderStats();
            m_Stats.elementsAdded   += m_StatsElementsAdded;
            m_Stats.elementsRemoved += m_StatsElementsRemoved;
            m_StatsElementsAdded     = m_StatsElementsRemoved = 0;


            int dirtyClass;
            RenderDataDirtyTypes dirtyFlags;
            RenderDataDirtyTypes clearDirty;

            m_DirtyTracker.dirtyID++;
            dirtyClass = (int)RenderDataDirtyTypeClasses.Clipping;
            dirtyFlags = RenderDataDirtyTypes.Clipping | RenderDataDirtyTypes.ClippingHierarchy;
            clearDirty = ~dirtyFlags;
            s_MarkerClipProcessing.Begin();
            for (int depth = m_DirtyTracker.minDepths[dirtyClass]; depth <= m_DirtyTracker.maxDepths[dirtyClass]; depth++)
            {
                VisualElement ve = m_DirtyTracker.heads[depth];
                while (ve != null)
                {
                    VisualElement veNext = ve.renderChainData.nextDirty;
                    if ((ve.renderChainData.dirtiedValues & dirtyFlags) != 0)
                    {
                        if (ve.renderChainData.isInChain && ve.renderChainData.dirtyID != m_DirtyTracker.dirtyID)
                        {
                            Implementation.RenderEvents.ProcessOnClippingChanged(this, ve, m_DirtyTracker.dirtyID,
                                                                                 ref m_Stats);
                        }
                        m_DirtyTracker.ClearDirty(ve, clearDirty);
                    }
                    ve = veNext;
                    m_Stats.dirtyProcessed++;
                }
            }
            s_MarkerClipProcessing.End();

            m_DirtyTracker.dirtyID++;
            dirtyClass = (int)RenderDataDirtyTypeClasses.Opacity;
            dirtyFlags = RenderDataDirtyTypes.Opacity | RenderDataDirtyTypes.OpacityHierarchy;
            clearDirty = ~dirtyFlags;
            s_MarkerOpacityProcessing.Begin();
            for (int depth = m_DirtyTracker.minDepths[dirtyClass]; depth <= m_DirtyTracker.maxDepths[dirtyClass]; depth++)
            {
                VisualElement ve = m_DirtyTracker.heads[depth];
                while (ve != null)
                {
                    VisualElement veNext = ve.renderChainData.nextDirty;
                    if ((ve.renderChainData.dirtiedValues & dirtyFlags) != 0)
                    {
                        if (ve.renderChainData.isInChain && ve.renderChainData.dirtyID != m_DirtyTracker.dirtyID)
                        {
                            Implementation.RenderEvents.ProcessOnOpacityChanged(this, ve, m_DirtyTracker.dirtyID, ref m_Stats);
                        }
                        m_DirtyTracker.ClearDirty(ve, clearDirty);
                    }
                    ve = veNext;
                    m_Stats.dirtyProcessed++;
                }
            }
            s_MarkerOpacityProcessing.End();

            m_DirtyTracker.dirtyID++;
            dirtyClass = (int)RenderDataDirtyTypeClasses.Color;
            dirtyFlags = RenderDataDirtyTypes.Color;
            clearDirty = ~dirtyFlags;
            s_MarkerColorsProcessing.Begin();
            for (int depth = m_DirtyTracker.minDepths[dirtyClass]; depth <= m_DirtyTracker.maxDepths[dirtyClass]; depth++)
            {
                VisualElement ve = m_DirtyTracker.heads[depth];
                while (ve != null)
                {
                    VisualElement veNext = ve.renderChainData.nextDirty;
                    if ((ve.renderChainData.dirtiedValues & dirtyFlags) != 0)
                    {
                        if (ve.renderChainData.isInChain && ve.renderChainData.dirtyID != m_DirtyTracker.dirtyID)
                        {
                            Implementation.RenderEvents.ProcessOnColorChanged(this, ve, m_DirtyTracker.dirtyID, ref m_Stats);
                        }
                        m_DirtyTracker.ClearDirty(ve, clearDirty);
                    }
                    ve = veNext;
                    m_Stats.dirtyProcessed++;
                }
            }
            s_MarkerColorsProcessing.End();

            m_DirtyTracker.dirtyID++;
            dirtyClass = (int)RenderDataDirtyTypeClasses.TransformSize;
            dirtyFlags = RenderDataDirtyTypes.Transform | RenderDataDirtyTypes.ClipRectSize;
            clearDirty = ~dirtyFlags;
            s_MarkerTransformProcessing.Begin();
            for (int depth = m_DirtyTracker.minDepths[dirtyClass]; depth <= m_DirtyTracker.maxDepths[dirtyClass]; depth++)
            {
                VisualElement ve = m_DirtyTracker.heads[depth];
                while (ve != null)
                {
                    VisualElement veNext = ve.renderChainData.nextDirty;
                    if ((ve.renderChainData.dirtiedValues & dirtyFlags) != 0)
                    {
                        if (ve.renderChainData.isInChain && ve.renderChainData.dirtyID != m_DirtyTracker.dirtyID)
                        {
                            Implementation.RenderEvents.ProcessOnTransformOrSizeChanged(this, ve, m_DirtyTracker.dirtyID, ref m_Stats);
                        }
                        m_DirtyTracker.ClearDirty(ve, clearDirty);
                    }
                    ve = veNext;
                    m_Stats.dirtyProcessed++;
                }
            }
            s_MarkerTransformProcessing.End();

            jobManager.CompleteNudgeJobs();

            m_BlockDirtyRegistration = true; // Processing visuals may call generateVisualContent, which must be restricted to the allowed operations
            m_DirtyTracker.dirtyID++;
            dirtyClass = (int)RenderDataDirtyTypeClasses.Visuals;
            dirtyFlags = RenderDataDirtyTypes.AllVisuals;
            clearDirty = ~dirtyFlags;
            s_MarkerVisualsProcessing.Begin();
            for (int depth = m_DirtyTracker.minDepths[dirtyClass]; depth <= m_DirtyTracker.maxDepths[dirtyClass]; depth++)
            {
                VisualElement ve = m_DirtyTracker.heads[depth];
                while (ve != null)
                {
                    VisualElement veNext = ve.renderChainData.nextDirty;
                    if ((ve.renderChainData.dirtiedValues & dirtyFlags) != 0)
                    {
                        if (ve.renderChainData.isInChain && ve.renderChainData.dirtyID != m_DirtyTracker.dirtyID)
                        {
                            Implementation.RenderEvents.ProcessOnVisualsChanged(this, ve, m_DirtyTracker.dirtyID, ref m_Stats);
                        }
                        m_DirtyTracker.ClearDirty(ve, clearDirty);
                    }
                    ve = veNext;
                    m_Stats.dirtyProcessed++;
                }
            }

            jobManager.CompleteConvertMeshJobs();
            jobManager.CompleteClosingMeshJobs();

            opacityIdAccelerator.CompleteJobs();
            s_MarkerVisualsProcessing.End();
            m_BlockDirtyRegistration = false;

            vertsPool.Reset();
            indicesPool.Reset();

            // Done with all dirtied elements
            m_DirtyTracker.Reset();


            // Commit new requests for atlases if any
            atlas?.InvokeUpdateDynamicTextures(panel); // TODO: For a shared atlas + drawInCameras, postpone after all updates have occurred.
            vectorImageManager?.Commit();
            shaderInfoAllocator.IssuePendingStorageChanges();

            device?.OnFrameRenderingBegin();

            s_MarkerProcess.End();
        }