Limit number of events that can be retrieved from GetDisplayVSyncEvent (#3188)
* Limit number of events that can be retrieved from GetDisplayVSyncEvent * Cleaning * Rename openDisplayInfos -> openDisplays
This commit is contained in:
parent
bb2f9df0a1
commit
fb7c80e928
5 changed files with 27 additions and 17 deletions
|
@ -16,7 +16,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi
|
||||||
|
|
||||||
if (serviceType != ViServiceType.Application)
|
if (serviceType != ViServiceType.Application)
|
||||||
{
|
{
|
||||||
return ResultCode.InvalidRange;
|
return ResultCode.PermissionDenied;
|
||||||
}
|
}
|
||||||
|
|
||||||
MakeObject(context, new IApplicationDisplayService(serviceType));
|
MakeObject(context, new IApplicationDisplayService(serviceType));
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi
|
||||||
|
|
||||||
if (serviceType != ViServiceType.Manager)
|
if (serviceType != ViServiceType.Manager)
|
||||||
{
|
{
|
||||||
return ResultCode.InvalidRange;
|
return ResultCode.PermissionDenied;
|
||||||
}
|
}
|
||||||
|
|
||||||
MakeObject(context, new IApplicationDisplayService(serviceType));
|
MakeObject(context, new IApplicationDisplayService(serviceType));
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi
|
||||||
|
|
||||||
if (serviceType != ViServiceType.System)
|
if (serviceType != ViServiceType.System)
|
||||||
{
|
{
|
||||||
return ResultCode.InvalidRange;
|
return ResultCode.PermissionDenied;
|
||||||
}
|
}
|
||||||
|
|
||||||
MakeObject(context, new IApplicationDisplayService(serviceType));
|
MakeObject(context, new IApplicationDisplayService(serviceType));
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi
|
||||||
|
|
||||||
InvalidArguments = (1 << ErrorCodeShift) | ModuleId,
|
InvalidArguments = (1 << ErrorCodeShift) | ModuleId,
|
||||||
InvalidLayerSize = (4 << ErrorCodeShift) | ModuleId,
|
InvalidLayerSize = (4 << ErrorCodeShift) | ModuleId,
|
||||||
InvalidRange = (5 << ErrorCodeShift) | ModuleId,
|
PermissionDenied = (5 << ErrorCodeShift) | ModuleId,
|
||||||
InvalidScalingMode = (6 << ErrorCodeShift) | ModuleId,
|
InvalidScalingMode = (6 << ErrorCodeShift) | ModuleId,
|
||||||
InvalidValue = (7 << ErrorCodeShift) | ModuleId,
|
InvalidValue = (7 << ErrorCodeShift) | ModuleId,
|
||||||
AlreadyOpened = (9 << ErrorCodeShift) | ModuleId
|
AlreadyOpened = (9 << ErrorCodeShift) | ModuleId
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using Ryujinx.Cpu;
|
|
||||||
using Ryujinx.HLE.HOS.Applets;
|
using Ryujinx.HLE.HOS.Applets;
|
||||||
using Ryujinx.HLE.HOS.Ipc;
|
using Ryujinx.HLE.HOS.Ipc;
|
||||||
using Ryujinx.HLE.HOS.Kernel.Common;
|
using Ryujinx.HLE.HOS.Kernel.Common;
|
||||||
|
@ -22,16 +21,21 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
|
||||||
{
|
{
|
||||||
private readonly ViServiceType _serviceType;
|
private readonly ViServiceType _serviceType;
|
||||||
|
|
||||||
private readonly List<DisplayInfo> _displayInfo;
|
private class DisplayState
|
||||||
private readonly Dictionary<ulong, DisplayInfo> _openDisplayInfo;
|
{
|
||||||
|
public int RetrievedEventsCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly List<DisplayInfo> _displayInfo;
|
||||||
|
private readonly Dictionary<ulong, DisplayState> _openDisplays;
|
||||||
|
|
||||||
private int _vsyncEventHandle;
|
private int _vsyncEventHandle;
|
||||||
|
|
||||||
public IApplicationDisplayService(ViServiceType serviceType)
|
public IApplicationDisplayService(ViServiceType serviceType)
|
||||||
{
|
{
|
||||||
_serviceType = serviceType;
|
_serviceType = serviceType;
|
||||||
_displayInfo = new List<DisplayInfo>();
|
_displayInfo = new List<DisplayInfo>();
|
||||||
_openDisplayInfo = new Dictionary<ulong, DisplayInfo>();
|
_openDisplays = new Dictionary<ulong, DisplayState>();
|
||||||
|
|
||||||
void AddDisplayInfo(string name, bool layerLimitEnabled, ulong layerLimitMax, ulong width, ulong height)
|
void AddDisplayInfo(string name, bool layerLimitEnabled, ulong layerLimitMax, ulong width, ulong height)
|
||||||
{
|
{
|
||||||
|
@ -64,7 +68,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
|
||||||
// FIXME: Should be _serviceType != ViServiceType.Application but guests crashes if we do this check.
|
// FIXME: Should be _serviceType != ViServiceType.Application but guests crashes if we do this check.
|
||||||
if (_serviceType > ViServiceType.System)
|
if (_serviceType > ViServiceType.System)
|
||||||
{
|
{
|
||||||
return ResultCode.InvalidRange;
|
return ResultCode.PermissionDenied;
|
||||||
}
|
}
|
||||||
|
|
||||||
MakeObject(context, new HOSBinderDriverServer());
|
MakeObject(context, new HOSBinderDriverServer());
|
||||||
|
@ -79,7 +83,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
|
||||||
// FIXME: Should be _serviceType == ViServiceType.System but guests crashes if we do this check.
|
// FIXME: Should be _serviceType == ViServiceType.System but guests crashes if we do this check.
|
||||||
if (_serviceType > ViServiceType.System)
|
if (_serviceType > ViServiceType.System)
|
||||||
{
|
{
|
||||||
return ResultCode.InvalidRange;
|
return ResultCode.PermissionDenied;
|
||||||
}
|
}
|
||||||
|
|
||||||
MakeObject(context, new ISystemDisplayService(this));
|
MakeObject(context, new ISystemDisplayService(this));
|
||||||
|
@ -93,7 +97,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
|
||||||
{
|
{
|
||||||
if (_serviceType > ViServiceType.System)
|
if (_serviceType > ViServiceType.System)
|
||||||
{
|
{
|
||||||
return ResultCode.InvalidRange;
|
return ResultCode.PermissionDenied;
|
||||||
}
|
}
|
||||||
|
|
||||||
MakeObject(context, new IManagerDisplayService(this));
|
MakeObject(context, new IManagerDisplayService(this));
|
||||||
|
@ -107,7 +111,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
|
||||||
{
|
{
|
||||||
if (_serviceType > ViServiceType.System)
|
if (_serviceType > ViServiceType.System)
|
||||||
{
|
{
|
||||||
return ResultCode.InvalidRange;
|
return ResultCode.PermissionDenied;
|
||||||
}
|
}
|
||||||
|
|
||||||
MakeObject(context, new HOSBinderDriverServer());
|
MakeObject(context, new HOSBinderDriverServer());
|
||||||
|
@ -174,7 +178,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
|
||||||
return ResultCode.InvalidValue;
|
return ResultCode.InvalidValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_openDisplayInfo.TryAdd((ulong)displayId, _displayInfo[displayId]))
|
if (!_openDisplays.TryAdd((ulong)displayId, new DisplayState()))
|
||||||
{
|
{
|
||||||
return ResultCode.AlreadyOpened;
|
return ResultCode.AlreadyOpened;
|
||||||
}
|
}
|
||||||
|
@ -190,7 +194,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
|
||||||
{
|
{
|
||||||
ulong displayId = context.RequestData.ReadUInt64();
|
ulong displayId = context.RequestData.ReadUInt64();
|
||||||
|
|
||||||
if (!_openDisplayInfo.Remove(displayId))
|
if (!_openDisplays.Remove(displayId))
|
||||||
{
|
{
|
||||||
return ResultCode.InvalidValue;
|
return ResultCode.InvalidValue;
|
||||||
}
|
}
|
||||||
|
@ -454,11 +458,16 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
|
||||||
{
|
{
|
||||||
ulong displayId = context.RequestData.ReadUInt64();
|
ulong displayId = context.RequestData.ReadUInt64();
|
||||||
|
|
||||||
if (!_openDisplayInfo.ContainsKey(displayId))
|
if (!_openDisplays.TryGetValue(displayId, out DisplayState displayState))
|
||||||
{
|
{
|
||||||
return ResultCode.InvalidValue;
|
return ResultCode.InvalidValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (displayState.RetrievedEventsCount > 0)
|
||||||
|
{
|
||||||
|
return ResultCode.PermissionDenied;
|
||||||
|
}
|
||||||
|
|
||||||
if (_vsyncEventHandle == 0)
|
if (_vsyncEventHandle == 0)
|
||||||
{
|
{
|
||||||
if (context.Process.HandleTable.GenerateHandle(context.Device.System.VsyncEvent.ReadableEvent, out _vsyncEventHandle) != KernelResult.Success)
|
if (context.Process.HandleTable.GenerateHandle(context.Device.System.VsyncEvent.ReadableEvent, out _vsyncEventHandle) != KernelResult.Success)
|
||||||
|
@ -467,6 +476,7 @@ namespace Ryujinx.HLE.HOS.Services.Vi.RootService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
displayState.RetrievedEventsCount++;
|
||||||
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_vsyncEventHandle);
|
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_vsyncEventHandle);
|
||||||
|
|
||||||
return ResultCode.Success;
|
return ResultCode.Success;
|
||||||
|
|
Reference in a new issue