Vixen
02b45cc4
csharp
public sealed class EglContext

A GLES context on an EGL display, and the surface it presents to.

No guide page documents this yet — the page shows what the code says about itself.

Remarks

The thing the GLES profiles were waiting for. GlProfile has modelled GLES 3.0 and 3.2 since the backend was written and the translation layer has differed by profile throughout — what was missing was a context to run one on, because Silk.NET.OpenGLES binds libGLESv2 and nothing in Silk.NET 2 binds EGL. This is that context: about twenty entry points behind IEglApi, and the sequence that turns a native window into something SilkGlesApi can load from.

It is a Silk IGLContext, which is what makes the loading one line. GL.GetApi(context) asks for every entry point by name; supplying the interface means SilkGlesApi needs no knowledge of EGL, and a windowing layer that already has a context of its own — SDL, an Activity's GLSurfaceView — can be passed to the same constructor instead of this.

The version ladder. A driver is asked for GLES 3.2 and then, if it refuses, for 3.0. That is the whole of the profile detection, and it is deliberately a request rather than a query: GL_VERSION can only be read through a context that already exists, so choosing by reading it would mean creating a context to decide which context to create. Every refusal in between is an EGL error, drained before the next attempt so a later failure is never reported with an earlier reason. A caller who names Profile gets one attempt and the driver's own error if it fails, because "3.2 or nothing" is a legitimate thing to want and silently getting 3.0 — with no compute, no storage buffers and no indirect draws — is not an answer to it.

Teardown is the construction sequence backwards, and it runs on a failed construction too. EGL leaks quietly: a display that was initialised and a context that was created outlive a constructor that threw between them, and on Android that is a process that cannot bring up graphics again after one bad start. So every step past the first is inside a try whose catch releases what exists so far.

One display, terminated on dispose. eglTerminate marks every resource on a display for deletion, so a second context sharing this display would lose its own when the first is disposed. Nothing in the engine creates two — a device owns a context and there is one device — and the case is called out here rather than guarded against, because a reference count that has never had two holders is a reference count nobody has tested.

Threading. A context is current on one thread, which is the thread that constructed it and the thread GlDevice replays on. Dispose releases EGL's per-thread state as well as the objects.

Fields and properties (8)

  • public GlProfile Profile

    Which dialect the driver gave, which is the one GlDevice should be told.

  • public (int Major, int Minor) EglVersion

    The EGL version the driver implements.

  • public nint Display

    The EGL display.

  • public nint Surface

    The surface being presented to.

  • public nint Handle

    The context, which is what Silk.NET calls the handle.

  • public IGLContextSource? Source

    Always .

  • public bool IsCurrent
  • public Int2 Size

    How big the surface is now, in pixels.

Methods (8)

  • public EglContext(IEglApi egl, in EglContextOptions options)

    Brings up a context, or throws saying which step failed and what EGL said.

  • public void MakeCurrent()
  • public void Clear()
  • public void SwapBuffers()
  • public void SwapInterval(int interval)
  • public nint GetProcAddress(string proc, int? slot = null)
  • public bool TryGetProcAddress(string proc, out nint addr, int? slot = null)
  • public void Dispose()

Used by (1)

  • EglContextTestsVixen.Graphics.OpenGL.Tests