Browse Source

Add OpenGlControlBase documentation (#19188)

pull/19207/head
Max Katz 7 months ago
committed by GitHub
parent
commit
c008fb8083
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 53
      src/Avalonia.OpenGL/Controls/OpenGlControlBase.cs
  2. 13
      src/Avalonia.OpenGL/GlInterface.cs

53
src/Avalonia.OpenGL/Controls/OpenGlControlBase.cs

@ -12,6 +12,21 @@ using System.ComponentModel;
namespace Avalonia.OpenGL.Controls
{
/// <summary>
/// Base class for controls that render using OpenGL.
/// Provides infrastructure for OpenGL context management, surface creation, and rendering lifecycle.
/// </summary>
/// <remarks>
/// <para>The control automatically manages OpenGL context creation, surface setup, and cleanup.</para>
/// <para>
/// <b>Important:</b> Any interaction with <see cref="GlInterface"/> should only happen within the
/// <see cref="OnOpenGlInit"/>, <see cref="OnOpenGlDeinit"/>, or <see cref="OnOpenGlRender"/> method overrides.
/// </para>
/// <para>
/// Avalonia ensures proper OpenGL context synchronization and makes the context current only during these method calls.
/// Accessing OpenGL functions outside of these methods may result in undefined behavior, crashes, or rendering corruption.
/// </para>
/// </remarks>
public abstract class OpenGlControlBase : Control
{
private CompositionSurfaceVisual? _visual;
@ -23,8 +38,15 @@ namespace Avalonia.OpenGL.Controls
[MemberNotNullWhen(true, nameof(_resources))]
private bool IsInitializedSuccessfully => _initialization is { Status: TaskStatus.RanToCompletion, Result: true };
/// <summary>
/// Gets the OpenGL version information for the current context.
/// </summary>
protected GlVersion GlVersion => _resources?.Context.Version ?? default;
/// <summary>
/// Initializes a new instance of the <see cref="OpenGlControlBase"/> class.
/// </summary>
public OpenGlControlBase()
{
_update = Update;
@ -57,12 +79,14 @@ namespace Avalonia.OpenGL.Controls
_initialization = null;
}
/// <inheritdoc/>
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
{
DoCleanup();
base.OnDetachedFromVisualTree(e);
}
/// <inheritdoc/>
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnAttachedToVisualTree(e);
@ -114,7 +138,8 @@ namespace Avalonia.OpenGL.Controls
return true;
}
/// <inheritdoc/>
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
if (_visual != null && change.Property == BoundsProperty)
@ -220,10 +245,14 @@ namespace Avalonia.OpenGL.Controls
return true;
}
/// <inheritdoc cref="Visual.InvalidateVisual"/>
[Obsolete("Use RequestNextFrameRendering()"), EditorBrowsable(EditorBrowsableState.Never)]
// ReSharper disable once MemberCanBeProtected.Global
public new void InvalidateVisual() => RequestNextFrameRendering();
/// <summary>
/// Requests that the control be rendered on the next frame.
/// </summary>
public void RequestNextFrameRendering()
{
if ((_initialization == null || IsInitializedSuccessfully) &&
@ -240,22 +269,38 @@ namespace Avalonia.OpenGL.Controls
return new PixelSize(Math.Max(1, (int)(Bounds.Width * scaling)),
Math.Max(1, (int)(Bounds.Height * scaling)));
}
/// <summary>
/// Called when the OpenGL context is first created.
/// </summary>
/// <param name="gl">The interface for making OpenGL calls. Use <see cref="GlInterface.GetProcAddress"/> to access additional APIs not covered by <see cref="GlInterface"/>.</param>
protected virtual void OnOpenGlInit(GlInterface gl)
{
}
/// <summary>
/// Called when the OpenGL context is being destroyed.
/// </summary>
/// <param name="gl">The OpenGL interface for making OpenGL calls. Use <see cref="GlInterface.GetProcAddress"/> to access additional APIs not covered by <see cref="GlInterface"/>.</param>
protected virtual void OnOpenGlDeinit(GlInterface gl)
{
}
/// <summary>
/// Called when the OpenGL context is lost and cannot be recovered.
/// </summary>
protected virtual void OnOpenGlLost()
{
}
/// <summary>
/// Called to render the OpenGL content for the current frame.
/// </summary>
/// <param name="gl">The OpenGL interface for making OpenGL calls. Use <see cref="GlInterface.GetProcAddress"/> to access additional APIs not covered by <see cref="GlInterface"/>.</param>
/// <param name="fb">The framebuffer ID to render into.</param>
protected abstract void OnOpenGlRender(GlInterface gl, int fb);
}
}

13
src/Avalonia.OpenGL/GlInterface.cs

@ -2,12 +2,20 @@ using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using Avalonia.Metadata;
using Avalonia.Platform.Interop;
using Avalonia.SourceGenerator;
using static Avalonia.OpenGL.GlConsts;
namespace Avalonia.OpenGL
{
/// <summary>
/// GlInterface only includes essential members and members necessary for Avalonia itself.
/// It is not a general-purpose interface for OpenGL API.
/// </summary>
/// <remarks>
/// Use <see cref="GlInterface.GetProcAddress"/> to get GL procedures you need, or integrate it with third-party GL wrappers.
/// </remarks>
public unsafe partial class GlInterface : GlBasicInfoInterface
{
private readonly Func<string, IntPtr> _getProcAddress;
@ -50,6 +58,11 @@ namespace Avalonia.OpenGL
{
}
/// <summary>
/// Returns an OpenGL function by name.
/// </summary>
/// <param name="proc">Function name.</param>
/// <returns>Handle of function, which can be casted to unmanaged function pointer.</returns>
public IntPtr GetProcAddress(string proc) => _getProcAddress(proc);
[GetProcAddress("glClearStencil")]

Loading…
Cancel
Save