mirror of
https://git.743378673.xyz/MeloNX/MeloNX.git
synced 2025-08-02 20:47:10 +02:00
Allow more than one process, free resources on process dispose, implement SvcExitThread
This commit is contained in:
parent
3aaa4717b6
commit
7a27990faa
46 changed files with 926 additions and 598 deletions
|
@ -1,5 +1,6 @@
|
|||
using ChocolArm64.Memory;
|
||||
using Ryujinx.Core.OsHle.Handles;
|
||||
using Ryujinx.Core.OsHle.IpcServices.NvServices;
|
||||
using Ryujinx.Graphics.Gal;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
|
@ -54,18 +55,27 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
|
|||
public GbpBuffer Data;
|
||||
}
|
||||
|
||||
private IGalRenderer Renderer;
|
||||
|
||||
private BufferEntry[] BufferQueue;
|
||||
|
||||
private ManualResetEvent WaitBufferFree;
|
||||
|
||||
private object RenderQueueLock;
|
||||
|
||||
private int RenderQueueCount;
|
||||
|
||||
private bool NvFlingerDisposed;
|
||||
|
||||
private bool KeepRunning;
|
||||
|
||||
public NvFlinger()
|
||||
public NvFlinger(IGalRenderer Renderer)
|
||||
{
|
||||
Commands = new Dictionary<(string, int), ServiceProcessParcel>()
|
||||
{
|
||||
{ ("android.gui.IGraphicBufferProducer", 0x1), GbpRequestBuffer },
|
||||
{ ("android.gui.IGraphicBufferProducer", 0x3), GbpDequeueBuffer },
|
||||
{ ("android.gui.IGraphicBufferProducer", 0x4), GbpDetachBuffer },
|
||||
{ ("android.gui.IGraphicBufferProducer", 0x7), GbpQueueBuffer },
|
||||
{ ("android.gui.IGraphicBufferProducer", 0x8), GbpCancelBuffer },
|
||||
{ ("android.gui.IGraphicBufferProducer", 0x9), GbpQuery },
|
||||
|
@ -74,10 +84,14 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
|
|||
{ ("android.gui.IGraphicBufferProducer", 0xe), GbpPreallocBuffer }
|
||||
};
|
||||
|
||||
this.Renderer = Renderer;
|
||||
|
||||
BufferQueue = new BufferEntry[0x40];
|
||||
|
||||
WaitBufferFree = new ManualResetEvent(false);
|
||||
|
||||
RenderQueueLock = new object();
|
||||
|
||||
KeepRunning = true;
|
||||
}
|
||||
|
||||
|
@ -193,6 +207,11 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
|
|||
return MakeReplyParcel(Context, 1280, 720, 0, 0, 0);
|
||||
}
|
||||
|
||||
private long GbpDetachBuffer(ServiceCtx Context, BinaryReader ParcelReader)
|
||||
{
|
||||
return MakeReplyParcel(Context, 0);
|
||||
}
|
||||
|
||||
private long GbpCancelBuffer(ServiceCtx Context, BinaryReader ParcelReader)
|
||||
{
|
||||
//TODO: Errors.
|
||||
|
@ -266,7 +285,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
|
|||
|
||||
long FbSize = (uint)FbWidth * FbHeight * 4;
|
||||
|
||||
HNvMap NvMap = GetNvMap(Context, Slot);
|
||||
NvMap NvMap = GetNvMap(Context, Slot);
|
||||
|
||||
if ((ulong)(NvMap.Address + FbSize) > AMemoryMgr.AddrSize)
|
||||
{
|
||||
|
@ -330,7 +349,17 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
|
|||
Rotate = -MathF.PI * 0.5f;
|
||||
}
|
||||
|
||||
byte* Fb = (byte*)Context.Ns.Memory.Ram + NvMap.Address;
|
||||
lock (RenderQueueLock)
|
||||
{
|
||||
if (NvFlingerDisposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Interlocked.Increment(ref RenderQueueCount);
|
||||
}
|
||||
|
||||
byte* Fb = (byte*)Context.Memory.Ram + NvMap.Address;
|
||||
|
||||
Context.Ns.Gpu.Renderer.QueueAction(delegate()
|
||||
{
|
||||
|
@ -346,6 +375,8 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
|
|||
|
||||
BufferQueue[Slot].State = BufferState.Free;
|
||||
|
||||
Interlocked.Decrement(ref RenderQueueCount);
|
||||
|
||||
lock (WaitBufferFree)
|
||||
{
|
||||
WaitBufferFree.Set();
|
||||
|
@ -353,7 +384,7 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
|
|||
});
|
||||
}
|
||||
|
||||
private HNvMap GetNvMap(ServiceCtx Context, int Slot)
|
||||
private NvMap GetNvMap(ServiceCtx Context, int Slot)
|
||||
{
|
||||
int NvMapHandle = BitConverter.ToInt32(BufferQueue[Slot].Data.RawData, 0x4c);
|
||||
|
||||
|
@ -366,7 +397,9 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
|
|||
NvMapHandle = BitConverter.ToInt32(RawValue, 0);
|
||||
}
|
||||
|
||||
return Context.Ns.Os.Handles.GetData<HNvMap>(NvMapHandle);
|
||||
ServiceNvDrv NvDrv = (ServiceNvDrv)Context.Process.Services.GetService("nvdrv");
|
||||
|
||||
return NvDrv.GetNvMap(NvMapHandle);
|
||||
}
|
||||
|
||||
private int GetFreeSlotBlocking(int Width, int Height)
|
||||
|
@ -432,10 +465,24 @@ namespace Ryujinx.Core.OsHle.IpcServices.Android
|
|||
Dispose(true);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
protected virtual void Dispose(bool Disposing)
|
||||
{
|
||||
if (disposing)
|
||||
if (Disposing && !NvFlingerDisposed)
|
||||
{
|
||||
lock (RenderQueueLock)
|
||||
{
|
||||
NvFlingerDisposed = true;
|
||||
}
|
||||
|
||||
//Ensure that all pending actions was sent before
|
||||
//we can safely assume that the class was disposed.
|
||||
while (RenderQueueCount > 0)
|
||||
{
|
||||
Thread.Yield();
|
||||
}
|
||||
|
||||
Renderer.ResetFrameBuffer();
|
||||
|
||||
lock (WaitBufferFree)
|
||||
{
|
||||
KeepRunning = false;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue