<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 System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using osu.Framework.Development;
using osu.Framework.Graphics.Batches;
using osu.Framework.Graphics.OpenGL.Textures;
using osu.Framework.Graphics.Shaders;
using osu.Framework.Threading;
using osuTK;
using osuTK.Graphics;
using osuTK.Graphics.ES30;
using osu.Framework.Statistics;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.OpenGL.Buffers;
using osu.Framework.Platform;
using osu.Framework.Timing;

namespace osu.Framework.Graphics.OpenGL
{
    public static class GLWrapper
    {
        /// <summary>
        /// Maximum number of <see cref="DrawNode"/>s a <see cref="Drawable"/> can draw with.
        /// This is a carefully-chosen number to enable the update and draw threads to work concurrently without causing unnecessary load.
        /// </summary>
        public const int MAX_DRAW_NODES = 3;

        /// <summary>
        /// The interval (in frames) before checking whether VBOs should be freed.
        /// VBOs may remain unused for at most double this length before they are recycled.
        /// </summary>
        private const int vbo_free_check_interval = 300;

        /// <summary>
        /// The amount of times <see cref="Reset"/> has been invoked.
        /// </summary>
        internal static ulong ResetId { get; private set; }

        public static ref readonly MaskingInfo CurrentMaskingInfo => ref currentMaskingInfo;
        private static MaskingInfo currentMaskingInfo;

        public static RectangleI Viewport { get; private set; }
        public static RectangleF Ortho { get; private set; }
        public static RectangleI Scissor { get; private set; }
        public static Vector2I ScissorOffset { get; private set; }
        public static Matrix4 ProjectionMatrix { get; set; }
        public static DepthInfo CurrentDepthInfo { get; private set; }

        public static float BackbufferDrawDepth { get; private set; }

        public static bool UsingBackbuffer => frame_buffer_stack.Peek() == DefaultFrameBuffer;

        public static int DefaultFrameBuffer;

        public static bool IsEmbedded { get; internal set; }

        /// <summary>
        /// Check whether we have an initialised and non-disposed GL context.
        /// </summary>
        public static bool HasContext => GraphicsContext.CurrentContext != null;

        public static int MaxTextureSize { get; private set; } = 4096; // default value is to allow roughly normal flow in cases we don't have a GL context, like headless CI.
        public static int MaxRenderBufferSize { get; private set; } = 4096; // default value is to allow roughly normal flow in cases we don't have a GL context, like headless CI.

        /// <summary>
        /// The maximum number of texture uploads to dequeue and upload per frame.
        /// Defaults to 32.
        /// </summary>
        public static int MaxTexturesUploadedPerFrame { get; set; } = 32;

        /// <summary>
        /// The maximum number of pixels to upload per frame.
        /// Defaults to 2 megapixels (8mb alloc).
        /// </summary>
        public static int MaxPixelsUploadedPerFrame { get; set; } = 1024 * 1024 * 2;

        private static readonly Scheduler reset_scheduler = new Scheduler(() => ThreadSafety.IsDrawThread, new StopwatchClock(true)); // force no thread set until we are actually on the draw thread.

        /// <summary>
        /// A queue from which a maximum of one operation is invoked per draw frame.
        /// </summary>
        private static readonly ConcurrentQueue<Action> expensive_operation_queue = new ConcurrentQueue<Action>();

        private static readonly ConcurrentQueue<TextureGL> texture_upload_queue = new ConcurrentQueue<TextureGL>();

        private static readonly List<IVertexBatch> batch_reset_list = new List<IVertexBatch>();

        private static readonly List<IVertexBuffer> vertex_buffers_in_use = new List<IVertexBuffer>();

        public static bool IsInitialized { get; private set; }

        private static WeakReference<GameHost> host;

        internal static void Initialize(GameHost host)
        {
            if (IsInitialized) return;

            if (host.Window is OsuTKWindow win)
                IsEmbedded = win.IsEmbedded;

            GLWrapper.host = new WeakReference<GameHost>(host);

            MaxTextureSize = GL.GetInteger(GetPName.MaxTextureSize);
            MaxRenderBufferSize = GL.GetInteger(GetPName.MaxRenderbufferSize);

            GL.Disable(EnableCap.StencilTest);
            GL.Enable(EnableCap.Blend);

            IsInitialized = true;

            host.UpdateThread.Scheduler.AddDelayed(checkPendingDisposals, 0, true);
        }

        private static readonly List<PendingDisposal> pending_disposal_actions = new List<PendingDisposal>();

        private class PendingDisposal
        {
            public int RemainingFrameDelay = MAX_DRAW_NODES;

            public readonly Action Action;

            public PendingDisposal(Action action)
            {
                Action = action;
            }
        }

        internal static void ScheduleDisposal(Action disposalAction)
        {
            if (host != null && host.TryGetTarget(out _))
            {
                lock (pending_disposal_actions)
                    pending_disposal_actions.Add(new PendingDisposal(disposalAction));
            }<commit_msg>Fix target scheduler incorrectly being update thread<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 System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using osu.Framework.Development;
using osu.Framework.Graphics.Batches;
using osu.Framework.Graphics.OpenGL.Textures;
using osu.Framework.Graphics.Shaders;
using osu.Framework.Threading;
using osuTK;
using osuTK.Graphics;
using osuTK.Graphics.ES30;
using osu.Framework.Statistics;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.OpenGL.Buffers;
using osu.Framework.Platform;
using osu.Framework.Timing;

namespace osu.Framework.Graphics.OpenGL
{
    public static class GLWrapper
    {
        /// <summary>
        /// Maximum number of <see cref="DrawNode"/>s a <see cref="Drawable"/> can draw with.
        /// This is a carefully-chosen number to enable the update and draw threads to work concurrently without causing unnecessary load.
        /// </summary>
        public const int MAX_DRAW_NODES = 3;

        /// <summary>
        /// The interval (in frames) before checking whether VBOs should be freed.
        /// VBOs may remain unused for at most double this length before they are recycled.
        /// </summary>
        private const int vbo_free_check_interval = 300;

        /// <summary>
        /// The amount of times <see cref="Reset"/> has been invoked.
        /// </summary>
        internal static ulong ResetId { get; private set; }

        public static ref readonly MaskingInfo CurrentMaskingInfo => ref currentMaskingInfo;
        private static MaskingInfo currentMaskingInfo;

        public static RectangleI Viewport { get; private set; }
        public static RectangleF Ortho { get; private set; }
        public static RectangleI Scissor { get; private set; }
        public static Vector2I ScissorOffset { get; private set; }
        public static Matrix4 ProjectionMatrix { get; set; }
        public static DepthInfo CurrentDepthInfo { get; private set; }

        public static float BackbufferDrawDepth { get; private set; }

        public static bool UsingBackbuffer => frame_buffer_stack.Peek() == DefaultFrameBuffer;

        public static int DefaultFrameBuffer;

        public static bool IsEmbedded { get; internal set; }

        /// <summary>
        /// Check whether we have an initialised and non-disposed GL context.
        /// </summary>
        public static bool HasContext => GraphicsContext.CurrentContext != null;

        public static int MaxTextureSize { get; private set; } = 4096; // default value is to allow roughly normal flow in cases we don't have a GL context, like headless CI.
        public static int MaxRenderBufferSize { get; private set; } = 4096; // default value is to allow roughly normal flow in cases we don't have a GL context, like headless CI.

        /// <summary>
        /// The maximum number of texture uploads to dequeue and upload per frame.
        /// Defaults to 32.
        /// </summary>
        public static int MaxTexturesUploadedPerFrame { get; set; } = 32;

        /// <summary>
        /// The maximum number of pixels to upload per frame.
        /// Defaults to 2 megapixels (8mb alloc).
        /// </summary>
        public static int MaxPixelsUploadedPerFrame { get; set; } = 1024 * 1024 * 2;

        private static readonly Scheduler reset_scheduler = new Scheduler(() => ThreadSafety.IsDrawThread, new StopwatchClock(true)); // force no thread set until we are actually on the draw thread.

        /// <summary>
        /// A queue from which a maximum of one operation is invoked per draw frame.
        /// </summary>
        private static readonly ConcurrentQueue<Action> expensive_operation_queue = new ConcurrentQueue<Action>();

        private static readonly ConcurrentQueue<TextureGL> texture_upload_queue = new ConcurrentQueue<TextureGL>();

        private static readonly List<IVertexBatch> batch_reset_list = new List<IVertexBatch>();

        private static readonly List<IVertexBuffer> vertex_buffers_in_use = new List<IVertexBuffer>();

        public static bool IsInitialized { get; private set; }

        private static WeakReference<GameHost> host;

        internal static void Initialize(GameHost host)
        {
            if (IsInitialized) return;

            if (host.Window is OsuTKWindow win)
                IsEmbedded = win.IsEmbedded;

            GLWrapper.host = new WeakReference<GameHost>(host);

            MaxTextureSize = GL.GetInteger(GetPName.MaxTextureSize);
            MaxRenderBufferSize = GL.GetInteger(GetPName.MaxRenderbufferSize);

            GL.Disable(EnableCap.StencilTest);
            GL.Enable(EnableCap.Blend);

            IsInitialized = true;

            reset_scheduler.AddDelayed(checkPendingDisposals, 0, true);
        }

        private static readonly List<PendingDisposal> pending_disposal_actions = new List<PendingDisposal>();

        private class PendingDisposal
        {
            public int RemainingFrameDelay = MAX_DRAW_NODES;

            public readonly Action Action;

            public PendingDisposal(Action action)
            {
                Action = action;
            }
        }

        internal static void ScheduleDisposal(Action disposalAction)
        {
            if (host != null && host.TryGetTarget(out _))
            {
                lock (pending_disposal_actions)
                    pending_disposal_actions.Add(new PendingDisposal(disposalAction));
            }
{'fraction_non_alphanumeric': 0.08191367287492277, 'fraction_numerical': 0.005649218818960191, 'mean_word_length': 2.6117309531399426, 'pattern_counts': {'":': 0, '<': 65, '<?xml version=': 0, '>': 73, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6975494', 'n_tokens_mistral': 3006, 'n_tokens_neox': 2861, 'n_words': 994}