mirror of
https://github.com/Ryujinx/Opentk.git
synced 2025-04-17 16:31:55 +00:00
164 lines
4.4 KiB
C#
164 lines
4.4 KiB
C#
#region --- License ---
|
|
/* Licensed under the MIT/X11 license.
|
|
* Copyright (c) 2011 Xamarin, Inc.
|
|
* Copyright 2013 Xamarin Inc
|
|
* This notice may not be removed from any source distribution.
|
|
* See license.txt for licensing detailed licensing details.
|
|
*/
|
|
#endregion
|
|
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
using Android.Util;
|
|
using Android.Views;
|
|
using Android.Runtime;
|
|
using Javax.Microedition.Khronos.Egl;
|
|
|
|
using OpenTK.Graphics;
|
|
using OpenTK.Platform.Egl;
|
|
|
|
namespace OpenTK.Platform.Android {
|
|
|
|
class AndroidGraphicsContext : EglContext
|
|
{
|
|
public AndroidGraphicsContext(GraphicsMode mode, EglWindowInfo window, IGraphicsContext sharedContext,
|
|
int major, int minor, GraphicsContextFlags flags)
|
|
: base(mode, window, sharedContext, major, minor, flags)
|
|
{
|
|
}
|
|
|
|
public AndroidGraphicsContext(ContextHandle handle, EglWindowInfo window, IGraphicsContext sharedContext,
|
|
int major, int minor, GraphicsContextFlags flags)
|
|
: base(handle, window, sharedContext, major, minor, flags)
|
|
{
|
|
}
|
|
|
|
protected override IntPtr GetStaticAddress(IntPtr function, RenderableFlags renderable)
|
|
{
|
|
return IntPtr.Zero;
|
|
}
|
|
}
|
|
|
|
public class AndroidWindow : IWindowInfo, IDisposable
|
|
{
|
|
bool disposed;
|
|
WeakReference refHolder;
|
|
private EglWindowInfo eglWindowInfo;
|
|
|
|
// Get native window from surface
|
|
[DllImport("android")]
|
|
private static extern IntPtr ANativeWindow_fromSurface(IntPtr jni, IntPtr surface);
|
|
|
|
// Get native window from surface
|
|
[DllImport("android")]
|
|
private static extern void ANativeWindow_release(IntPtr surface);
|
|
|
|
public IntPtr Handle { get { return eglWindowInfo != null ? eglWindowInfo.Handle : IntPtr.Zero; } }
|
|
|
|
public bool HasSurface
|
|
{
|
|
get { return eglWindowInfo.Surface != IntPtr.Zero; }
|
|
}
|
|
|
|
public ISurfaceHolder Holder {
|
|
get {
|
|
return refHolder.Target as ISurfaceHolder;
|
|
}
|
|
}
|
|
public AndroidWindow (ISurfaceHolder holder)
|
|
{
|
|
refHolder = new WeakReference (holder);
|
|
}
|
|
|
|
internal EglWindowInfo CreateEglWindowInfo()
|
|
{
|
|
UpdateEglWindowInfo();
|
|
return eglWindowInfo;
|
|
}
|
|
|
|
public void CreateSurface(IntPtr config)
|
|
{
|
|
UpdateEglWindowInfo();
|
|
|
|
if (refHolder.Target == null) {
|
|
eglWindowInfo.CreatePbufferSurface(config);
|
|
return;
|
|
}
|
|
|
|
eglWindowInfo.CreateWindowSurface(config);
|
|
}
|
|
|
|
private void UpdateEglWindowInfo()
|
|
{
|
|
if (eglWindowInfo == null)
|
|
eglWindowInfo = new EglWindowInfo(IntPtr.Zero, IntPtr.Zero);
|
|
|
|
var newHandle = IntPtr.Zero;
|
|
var holder = Holder;
|
|
if (holder != null && holder.Surface != null)
|
|
{
|
|
newHandle = ANativeWindow_fromSurface(JNIEnv.Handle, holder.Surface.Handle);
|
|
}
|
|
|
|
// Do we need to recreate eglWindowInfo?
|
|
if (eglWindowInfo != null && eglWindowInfo.Handle == newHandle)
|
|
{
|
|
// Same, we can release this reference
|
|
if (newHandle != IntPtr.Zero)
|
|
ANativeWindow_release(newHandle);
|
|
}
|
|
else
|
|
{
|
|
DestroySurface();
|
|
|
|
eglWindowInfo.Handle = newHandle;
|
|
}
|
|
}
|
|
|
|
public void DestroySurface ()
|
|
{
|
|
eglWindowInfo.DestroySurface();
|
|
|
|
// Release window handle
|
|
if (eglWindowInfo.Handle != IntPtr.Zero)
|
|
{
|
|
ANativeWindow_release(eglWindowInfo.Handle);
|
|
eglWindowInfo.Handle = IntPtr.Zero;
|
|
}
|
|
}
|
|
|
|
public void TerminateDisplay ()
|
|
{
|
|
eglWindowInfo.TerminateDisplay();
|
|
}
|
|
|
|
#region IDisposable Members
|
|
|
|
public void Dispose ()
|
|
{
|
|
Dispose (true);
|
|
GC.SuppressFinalize (this);
|
|
}
|
|
|
|
void Dispose (bool disposing)
|
|
{
|
|
if (!disposed)
|
|
{
|
|
if (disposing) {
|
|
DestroySurface ();
|
|
TerminateDisplay ();
|
|
refHolder = null;
|
|
disposed = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
~AndroidWindow ()
|
|
{
|
|
Dispose (false);
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|