<commit_before>﻿// Copyright (c) ppy Pty Ltd <<EMAIL>>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Framework.Graphics.OpenGL;
using System;
using System.Runtime.CompilerServices;
using osu.Framework.Graphics.Batches;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.OpenGL.Buffers;
using osu.Framework.Graphics.OpenGL.Textures;
using osu.Framework.Graphics.OpenGL.Vertices;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Textures;
using osu.Framework.MathUtils.Clipping;
using osu.Framework.Threading;
using osuTK;

namespace osu.Framework.Graphics
{
    /// <summary>
    /// Contains all the information required to draw a single <see cref="Drawable"/>.
    /// A hierarchy of <see cref="DrawNode"/>s is passed to the draw thread for rendering every frame.
    /// </summary>
    public class DrawNode : IDisposable
    {
        /// <summary>
        /// Contains the linear transformation of this <see cref="DrawNode"/>.
        /// </summary>
        protected DrawInfo DrawInfo { get; private set; }

        /// <summary>
        /// Contains the colour and blending information of this <see cref="DrawNode"/>.
        /// </summary>
        protected DrawColourInfo DrawColourInfo { get; private set; }

        /// <summary>
        /// Identifies the state of this draw node with an invalidation state of its corresponding
        /// <see cref="Drawable"/>. An update is required when the invalidation state of this draw node disagrees
        /// with the invalidation state of its <see cref="Drawable"/>.
        /// </summary>
        protected internal long InvalidationID { get; private set; }

        /// <summary>
        /// The <see cref="Drawable"/> which this <see cref="DrawNode"/> draws.
        /// </summary>
        protected readonly IDrawable Source;

        private readonly AtomicCounter referenceCount = new AtomicCounter();

        /// <summary>
        /// The depth at which drawing should take place.
        /// This is written to from the front-to-back pass and used in both passes.
        /// </summary>
        private float drawDepth;

        /// <summary>
        /// Creates a new <see cref="DrawNode"/>.
        /// </summary>
        /// <param name="source">The <see cref="Drawable"/> to draw with this <see cref="DrawNode"/>.</param>
        public DrawNode(IDrawable source)
        {
            Source = source;

            Reference();
        }

        /// <summary>
        /// Applies the state of <see cref="Source"/> to this <see cref="DrawNode"/> for use in rendering.
        /// The applied state must remain immutable.
        /// </summary>
        public virtual void ApplyState()
        {
            DrawInfo = Source.DrawInfo;
            DrawColourInfo = Source.DrawColourInfo;
            InvalidationID = Source.InvalidationID;
        }

        /// <summary>
        /// Draws this <see cref="DrawNode"/> to the screen.
        /// </summary>
        /// <remarks>
        /// Subclasses must invoke <code>base.Draw()</code> prior to drawing this <see cref="DrawNode"/> to the screen.
        /// </remarks>
        /// <param name="vertexAction">The action to be performed on each vertex of the draw node in order to draw it if required. This is primarily used by textured sprites.</param>
        public virtual void Draw(Action<TexturedVertex2D> vertexAction)
        {
            GLWrapper.SetBlend(DrawColourInfo.Blending);

            // This is the back-to-front (BTF) pass. The back-buffer depth test function used is GL_LESS.
            // The depth test will fail for samples that overlap the opaque interior of this <see cref="DrawNode"/> and any <see cref="DrawNode"/>s above this one.
            GLWrapper.SetDrawDepth(drawDepth);
        }

        /// <summary>
        /// Draws the opaque interior of this <see cref="DrawNode"/> and all <see cref="DrawNode"/>s further down the scene graph, invoking <see cref="DrawOpaqueInterior"/> if <see cref="CanDrawOpaqueInterior"/>
        /// indicates that an opaque interior can be drawn for each relevant <see cref="DrawNode"/>.
        /// </summary>
        /// <remarks>
        /// This is the front-to-back pass. The back-buffer depth test function used is GL_LESS.<br />
        /// If an opaque interior is not drawn: the current value of <paramref name="depthValue"/> is stored.<br />
        /// If an opaque interior is drawn: <paramref name="depthValue"/> is incremented, stored, and the opaque interior vertices are drawn at the post-incremented depth value.
        /// Incrementing <paramref name="depthValue"/> at this point allows for early-z testing to also occur within the front-to-back pass.<br />
        /// </remarks>
        /// <param name="depthValue">The previous depth value.</param>
        /// <param name="vertexAction">The action to be performed on each vertex of the draw node in order to draw it if required. This is primarily used by textured sprites.</param>
        internal virtual void DrawOpaqueInteriorSubTree(DepthValue depthValue, Action<TexturedVertex2D> vertexAction)
        {
            if (!depthValue.CanIncrement || !CanDrawOpaqueInterior)
            {
                // The back-to-front pass requires the depth value
                drawDepth = depthValue;
                return;
            }

            // It is crucial to draw with an incremented depth value, consider the case of a box:
            // In the front-to-back pass, the inner conservative area is drawn at depth X
            // In the back-to-front pass, the full area is drawn at depth X, and the depth test function is set to GL_LESS, so the inner conservative area is not redrawn
            // Furthermore, a back-to-front-drawn object above the box will be visible since it will be drawn with a depth of (X - increment), satisfying the depth test
            drawDepth = depthValue.Increment();

            DrawOpaqueInterior(vertexAction);
        }

        /// <summary>
        /// Draws the opaque interior of this <see cref="DrawNode"/> to the screen.
        /// The opaque interior must be a fully-opaque, non-blended area of this <see cref="DrawNode"/>, clipped to the current masking area via <code>DrawClipped()</code>.
        /// See <see cref="Shapes.Box.BoxDrawNode"/> for an example implementation.
        /// </summary>
        /// <remarks>
        /// Subclasses must invoke <code>base.Draw()</code> prior to drawing the opaque interior of this <see cref="DrawNode"/> to the screen.
        /// </remarks>
        /// <param name="vertexAction">The action to be performed on each vertex of the draw node in order to draw it if required. This is primarily used by textured sprites.</param><commit_msg>Adjust comments to be more explicit<commit_after>﻿// Copyright (c) ppy Pty Ltd <<EMAIL>>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using osu.Framework.Graphics.OpenGL;
using System;
using System.Runtime.CompilerServices;
using osu.Framework.Graphics.Batches;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.OpenGL.Buffers;
using osu.Framework.Graphics.OpenGL.Textures;
using osu.Framework.Graphics.OpenGL.Vertices;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Textures;
using osu.Framework.MathUtils.Clipping;
using osu.Framework.Threading;
using osuTK;

namespace osu.Framework.Graphics
{
    /// <summary>
    /// Contains all the information required to draw a single <see cref="Drawable"/>.
    /// A hierarchy of <see cref="DrawNode"/>s is passed to the draw thread for rendering every frame.
    /// </summary>
    public class DrawNode : IDisposable
    {
        /// <summary>
        /// Contains the linear transformation of this <see cref="DrawNode"/>.
        /// </summary>
        protected DrawInfo DrawInfo { get; private set; }

        /// <summary>
        /// Contains the colour and blending information of this <see cref="DrawNode"/>.
        /// </summary>
        protected DrawColourInfo DrawColourInfo { get; private set; }

        /// <summary>
        /// Identifies the state of this draw node with an invalidation state of its corresponding
        /// <see cref="Drawable"/>. An update is required when the invalidation state of this draw node disagrees
        /// with the invalidation state of its <see cref="Drawable"/>.
        /// </summary>
        protected internal long InvalidationID { get; private set; }

        /// <summary>
        /// The <see cref="Drawable"/> which this <see cref="DrawNode"/> draws.
        /// </summary>
        protected readonly IDrawable Source;

        private readonly AtomicCounter referenceCount = new AtomicCounter();

        /// <summary>
        /// The depth at which drawing should take place.
        /// This is written to from the front-to-back pass and used in both passes.
        /// </summary>
        private float drawDepth;

        /// <summary>
        /// Creates a new <see cref="DrawNode"/>.
        /// </summary>
        /// <param name="source">The <see cref="Drawable"/> to draw with this <see cref="DrawNode"/>.</param>
        public DrawNode(IDrawable source)
        {
            Source = source;

            Reference();
        }

        /// <summary>
        /// Applies the state of <see cref="Source"/> to this <see cref="DrawNode"/> for use in rendering.
        /// The applied state must remain immutable.
        /// </summary>
        public virtual void ApplyState()
        {
            DrawInfo = Source.DrawInfo;
            DrawColourInfo = Source.DrawColourInfo;
            InvalidationID = Source.InvalidationID;
        }

        /// <summary>
        /// Draws this <see cref="DrawNode"/> to the screen.
        /// </summary>
        /// <remarks>
        /// Subclasses must invoke <code>base.Draw()</code> prior to drawing vertices.
        /// </remarks>
        /// <param name="vertexAction">The action to be performed on each vertex of the draw node in order to draw it if required. This is primarily used by textured sprites.</param>
        public virtual void Draw(Action<TexturedVertex2D> vertexAction)
        {
            GLWrapper.SetBlend(DrawColourInfo.Blending);

            // This is the back-to-front (BTF) pass. The back-buffer depth test function used is GL_LESS.
            // The depth test will fail for samples that overlap the opaque interior of this <see cref="DrawNode"/> and any <see cref="DrawNode"/>s above this one.
            GLWrapper.SetDrawDepth(drawDepth);
        }

        /// <summary>
        /// Draws the opaque interior of this <see cref="DrawNode"/> and all <see cref="DrawNode"/>s further down the scene graph, invoking <see cref="DrawOpaqueInterior"/> if <see cref="CanDrawOpaqueInterior"/>
        /// indicates that an opaque interior can be drawn for each relevant <see cref="DrawNode"/>.
        /// </summary>
        /// <remarks>
        /// This is the front-to-back pass. The back-buffer depth test function used is GL_LESS.<br />
        /// If an opaque interior is not drawn: the current value of <paramref name="depthValue"/> is stored.<br />
        /// If an opaque interior is drawn: <paramref name="depthValue"/> is incremented, stored, and the opaque interior vertices are drawn at the post-incremented depth value.
        /// Incrementing <paramref name="depthValue"/> at this point allows for early-z testing to also occur within the front-to-back pass.<br />
        /// </remarks>
        /// <param name="depthValue">The previous depth value.</param>
        /// <param name="vertexAction">The action to be performed on each vertex of the draw node in order to draw it if required. This is primarily used by textured sprites.</param>
        internal virtual void DrawOpaqueInteriorSubTree(DepthValue depthValue, Action<TexturedVertex2D> vertexAction)
        {
            if (!depthValue.CanIncrement || !CanDrawOpaqueInterior)
            {
                // The back-to-front pass requires the depth value
                drawDepth = depthValue;
                return;
            }

            // It is crucial to draw with an incremented depth value, consider the case of a box:
            // In the front-to-back pass, the inner conservative area is drawn at depth X
            // In the back-to-front pass, the full area is drawn at depth X, and the depth test function is set to GL_LESS, so the inner conservative area is not redrawn
            // Furthermore, a back-to-front-drawn object above the box will be visible since it will be drawn with a depth of (X - increment), satisfying the depth test
            drawDepth = depthValue.Increment();

            DrawOpaqueInterior(vertexAction);
        }

        /// <summary>
        /// Draws the opaque interior of this <see cref="DrawNode"/> to the screen.
        /// The opaque interior must be a fully-opaque, non-blended area of this <see cref="DrawNode"/>, clipped to the current masking area via <code>DrawClipped()</code>.
        /// See <see cref="Shapes.Box.BoxDrawNode"/> for an example implementation.
        /// </summary>
        /// <remarks>
        /// Subclasses must invoke <code>base.DrawOpaqueInterior()</code> prior to drawing vertices.
        /// </remarks>
        /// <param name="vertexAction">The action to be performed on each vertex of the draw node in order to draw it if required. This is primarily used by textured sprites.</param>
{'fraction_non_alphanumeric': 0.10754591723832706, 'fraction_numerical': 0.00029505052740281775, 'mean_word_length': 2.355940594059406, 'pattern_counts': {'":': 0, '<': 161, '<?xml version=': 0, '>': 161, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3499130', 'n_tokens_mistral': 3487, 'n_tokens_neox': 3425, 'n_words': 1376}