mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-07-19 18:16:54 +02:00
[Ryujinx.HLE] Address dotnet-format issues (#5380)
* dotnet format style --severity info Some changes were manually reverted. * dotnet format analyzers --serverity info Some changes have been minimally adapted. * Restore a few unused methods and variables * Silence dotnet format IDE0060 warnings * Silence dotnet format IDE0052 warnings * Address or silence dotnet format IDE1006 warnings * Address dotnet format CA1816 warnings * Address or silence dotnet format CA2208 warnings * Address or silence dotnet format CA1806 and a few CA1854 warnings * Address dotnet format CA2211 warnings * Address dotnet format CA1822 warnings * Address or silence dotnet format CA1069 warnings * Make dotnet format succeed in style mode * Address or silence dotnet format CA2211 warnings * Address review comments * Address dotnet format CA2208 warnings properly * Make ProcessResult readonly * Address most dotnet format whitespace warnings * Apply dotnet format whitespace formatting A few of them have been manually reverted and the corresponding warning was silenced * Add previously silenced warnings back I have no clue how these disappeared * Revert formatting changes for while and for-loops * Format if-blocks correctly * Run dotnet format style after rebase * Run dotnet format whitespace after rebase * Run dotnet format style after rebase * Run dotnet format analyzers after rebase * Run dotnet format after rebase and remove unused usings - analyzers - style - whitespace * Disable 'prefer switch expression' rule * Add comments to disabled warnings * Fix a few disabled warnings * Fix naming rule violation, Convert shader properties to auto-property and convert values to const * Simplify properties and array initialization, Use const when possible, Remove trailing commas * Start working on disabled warnings * Fix and silence a few dotnet-format warnings again * Run dotnet format after rebase * Use using declaration instead of block syntax * Address IDE0251 warnings * Address a few disabled IDE0060 warnings * Silence IDE0060 in .editorconfig * Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas" This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e. * dotnet format whitespace after rebase * First dotnet format pass * Fix naming rule violations * Fix typo * Add trailing commas, use targeted new and use array initializer * Fix build issues * Fix remaining build issues * Remove SuppressMessage for CA1069 where possible * Address dotnet format issues * Address formatting issues Co-authored-by: Ac_K <acoustik666@gmail.com> * Add GetHashCode implementation for RenderingSurfaceInfo * Explicitly silence CA1822 for every affected method in Syscall * Address formatting issues in Demangler.cs * Address review feedback Co-authored-by: Ac_K <acoustik666@gmail.com> * Revert marking service methods as static * Next dotnet format pass * Address review feedback --------- Co-authored-by: Ac_K <acoustik666@gmail.com>
This commit is contained in:
parent
fec8291c17
commit
326749498b
1015 changed files with 8173 additions and 7615 deletions
|
@ -5,7 +5,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
{
|
||||
class BufferItemConsumer : ConsumerBase
|
||||
{
|
||||
private GpuContext _gpuContext;
|
||||
private readonly GpuContext _gpuContext;
|
||||
|
||||
public BufferItemConsumer(Switch device,
|
||||
BufferQueueConsumer consumer,
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
{
|
||||
public static BufferQueueCore CreateBufferQueue(Switch device, ulong pid, out BufferQueueProducer producer, out BufferQueueConsumer consumer)
|
||||
{
|
||||
BufferQueueCore core = new BufferQueueCore(device, pid);
|
||||
BufferQueueCore core = new(device, pid);
|
||||
|
||||
producer = new BufferQueueProducer(core, device.System.TickSource);
|
||||
consumer = new BufferQueueConsumer(core);
|
||||
|
|
|
@ -54,10 +54,10 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
if (Core.StillTracking(ref bufferItem))
|
||||
{
|
||||
Core.Slots[bufferItem.Slot].AcquireCalled = true;
|
||||
Core.Slots[bufferItem.Slot].AcquireCalled = true;
|
||||
Core.Slots[bufferItem.Slot].NeedsCleanupOnRelease = true;
|
||||
Core.Slots[bufferItem.Slot].BufferState = BufferState.Acquired;
|
||||
Core.Slots[bufferItem.Slot].Fence = AndroidFence.NoFence;
|
||||
Core.Slots[bufferItem.Slot].BufferState = BufferState.Acquired;
|
||||
Core.Slots[bufferItem.Slot].Fence = AndroidFence.NoFence;
|
||||
|
||||
ulong targetFrameNumber = Core.Slots[bufferItem.Slot].FrameNumber;
|
||||
|
||||
|
@ -159,12 +159,12 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
Core.Slots[slot].GraphicBuffer.Set(graphicBuffer);
|
||||
|
||||
Core.Slots[slot].BufferState = BufferState.Acquired;
|
||||
Core.Slots[slot].AttachedByConsumer = true;
|
||||
Core.Slots[slot].BufferState = BufferState.Acquired;
|
||||
Core.Slots[slot].AttachedByConsumer = true;
|
||||
Core.Slots[slot].NeedsCleanupOnRelease = false;
|
||||
Core.Slots[slot].Fence = AndroidFence.NoFence;
|
||||
Core.Slots[slot].FrameNumber = 0;
|
||||
Core.Slots[slot].AcquireCalled = false;
|
||||
Core.Slots[slot].Fence = AndroidFence.NoFence;
|
||||
Core.Slots[slot].FrameNumber = 0;
|
||||
Core.Slots[slot].AcquireCalled = false;
|
||||
}
|
||||
|
||||
return Status.Success;
|
||||
|
@ -197,7 +197,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
if (Core.Slots[slot].BufferState == BufferState.Acquired)
|
||||
{
|
||||
Core.Slots[slot].BufferState = BufferState.Free;
|
||||
Core.Slots[slot].Fence = fence;
|
||||
Core.Slots[slot].Fence = fence;
|
||||
|
||||
listener = Core.ProducerListener;
|
||||
}
|
||||
|
@ -237,7 +237,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
return Status.NoInit;
|
||||
}
|
||||
|
||||
Core.ConsumerListener = consumerListener;
|
||||
Core.ConsumerListener = consumerListener;
|
||||
Core.ConsumerControlledByApp = controlledByApp;
|
||||
}
|
||||
|
||||
|
@ -253,7 +253,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
return Status.BadValue;
|
||||
}
|
||||
|
||||
Core.IsAbandoned = true;
|
||||
Core.IsAbandoned = true;
|
||||
Core.ConsumerListener = null;
|
||||
|
||||
Core.Queue.Clear();
|
||||
|
@ -304,7 +304,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
lock (Core.Lock)
|
||||
{
|
||||
Core.DefaultWidth = (int)width;
|
||||
Core.DefaultWidth = (int)width;
|
||||
Core.DefaultHeight = (int)height;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,35 +9,35 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
{
|
||||
class BufferQueueCore
|
||||
{
|
||||
public BufferSlotArray Slots;
|
||||
public int OverrideMaxBufferCount;
|
||||
public bool UseAsyncBuffer;
|
||||
public bool DequeueBufferCannotBlock;
|
||||
public PixelFormat DefaultBufferFormat;
|
||||
public int DefaultWidth;
|
||||
public int DefaultHeight;
|
||||
public int DefaultMaxBufferCount;
|
||||
public int MaxAcquiredBufferCount;
|
||||
public bool BufferHasBeenQueued;
|
||||
public ulong FrameCounter;
|
||||
public BufferSlotArray Slots;
|
||||
public int OverrideMaxBufferCount;
|
||||
public bool UseAsyncBuffer;
|
||||
public bool DequeueBufferCannotBlock;
|
||||
public PixelFormat DefaultBufferFormat;
|
||||
public int DefaultWidth;
|
||||
public int DefaultHeight;
|
||||
public int DefaultMaxBufferCount;
|
||||
public int MaxAcquiredBufferCount;
|
||||
public bool BufferHasBeenQueued;
|
||||
public ulong FrameCounter;
|
||||
public NativeWindowTransform TransformHint;
|
||||
public bool IsAbandoned;
|
||||
public NativeWindowApi ConnectedApi;
|
||||
public bool IsAllocating;
|
||||
public IProducerListener ProducerListener;
|
||||
public IConsumerListener ConsumerListener;
|
||||
public bool ConsumerControlledByApp;
|
||||
public uint ConsumerUsageBits;
|
||||
public List<BufferItem> Queue;
|
||||
public BufferInfo[] BufferHistory;
|
||||
public uint BufferHistoryPosition;
|
||||
public bool EnableExternalEvent;
|
||||
public int MaxBufferCountCached;
|
||||
public bool IsAbandoned;
|
||||
public NativeWindowApi ConnectedApi;
|
||||
public bool IsAllocating;
|
||||
public IProducerListener ProducerListener;
|
||||
public IConsumerListener ConsumerListener;
|
||||
public bool ConsumerControlledByApp;
|
||||
public uint ConsumerUsageBits;
|
||||
public List<BufferItem> Queue;
|
||||
public BufferInfo[] BufferHistory;
|
||||
public uint BufferHistoryPosition;
|
||||
public bool EnableExternalEvent;
|
||||
public int MaxBufferCountCached;
|
||||
|
||||
public readonly object Lock = new();
|
||||
|
||||
private KEvent _waitBufferFreeEvent;
|
||||
private KEvent _frameAvailableEvent;
|
||||
private readonly KEvent _waitBufferFreeEvent;
|
||||
private readonly KEvent _frameAvailableEvent;
|
||||
|
||||
public ulong Owner { get; }
|
||||
|
||||
|
@ -49,36 +49,36 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
public BufferQueueCore(Switch device, ulong pid)
|
||||
{
|
||||
Slots = new BufferSlotArray();
|
||||
IsAbandoned = false;
|
||||
OverrideMaxBufferCount = 0;
|
||||
Slots = new BufferSlotArray();
|
||||
IsAbandoned = false;
|
||||
OverrideMaxBufferCount = 0;
|
||||
DequeueBufferCannotBlock = false;
|
||||
UseAsyncBuffer = false;
|
||||
DefaultWidth = 1;
|
||||
DefaultHeight = 1;
|
||||
DefaultMaxBufferCount = 2;
|
||||
MaxAcquiredBufferCount = 1;
|
||||
FrameCounter = 0;
|
||||
TransformHint = 0;
|
||||
DefaultBufferFormat = PixelFormat.Rgba8888;
|
||||
IsAllocating = false;
|
||||
ProducerListener = null;
|
||||
ConsumerListener = null;
|
||||
ConsumerUsageBits = 0;
|
||||
UseAsyncBuffer = false;
|
||||
DefaultWidth = 1;
|
||||
DefaultHeight = 1;
|
||||
DefaultMaxBufferCount = 2;
|
||||
MaxAcquiredBufferCount = 1;
|
||||
FrameCounter = 0;
|
||||
TransformHint = 0;
|
||||
DefaultBufferFormat = PixelFormat.Rgba8888;
|
||||
IsAllocating = false;
|
||||
ProducerListener = null;
|
||||
ConsumerListener = null;
|
||||
ConsumerUsageBits = 0;
|
||||
|
||||
Queue = new List<BufferItem>();
|
||||
|
||||
// TODO: CreateGraphicBufferAlloc?
|
||||
|
||||
_waitBufferFreeEvent = new KEvent(device.System.KernelContext);
|
||||
_waitBufferFreeEvent = new KEvent(device.System.KernelContext);
|
||||
_frameAvailableEvent = new KEvent(device.System.KernelContext);
|
||||
|
||||
Owner = pid;
|
||||
|
||||
Active = true;
|
||||
|
||||
BufferHistory = new BufferInfo[BufferHistoryArraySize];
|
||||
EnableExternalEvent = true;
|
||||
BufferHistory = new BufferInfo[BufferHistoryArraySize];
|
||||
EnableExternalEvent = true;
|
||||
MaxBufferCountCached = 0;
|
||||
}
|
||||
|
||||
|
@ -220,9 +220,9 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
Slots[slot].NeedsCleanupOnRelease = true;
|
||||
}
|
||||
|
||||
Slots[slot].BufferState = BufferState.Free;
|
||||
Slots[slot].FrameNumber = uint.MaxValue;
|
||||
Slots[slot].AcquireCalled = false;
|
||||
Slots[slot].BufferState = BufferState.Free;
|
||||
Slots[slot].FrameNumber = uint.MaxValue;
|
||||
Slots[slot].AcquireCalled = false;
|
||||
Slots[slot].Fence.FenceCount = 0;
|
||||
}
|
||||
|
||||
|
@ -259,7 +259,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
return;
|
||||
}
|
||||
|
||||
bool needBufferReleaseSignal = false;
|
||||
bool needBufferReleaseSignal = false;
|
||||
bool needFrameAvailableSignal = false;
|
||||
|
||||
if (maxBufferCount > 1)
|
||||
|
|
|
@ -15,7 +15,9 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
private readonly ITickSource _tickSource;
|
||||
|
||||
#pragma warning disable IDE0052 // Remove unread private member
|
||||
private uint _stickyTransform;
|
||||
#pragma warning restore IDE0052
|
||||
|
||||
private uint _nextCallbackTicket;
|
||||
private uint _currentCallbackTicket;
|
||||
|
@ -28,9 +30,9 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
Core = core;
|
||||
_tickSource = tickSource;
|
||||
|
||||
_stickyTransform = 0;
|
||||
_callbackTicket = 0;
|
||||
_nextCallbackTicket = 0;
|
||||
_stickyTransform = 0;
|
||||
_callbackTicket = 0;
|
||||
_nextCallbackTicket = 0;
|
||||
_currentCallbackTicket = 0;
|
||||
}
|
||||
|
||||
|
@ -134,7 +136,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
{
|
||||
if ((width == 0 && height != 0) || (height == 0 && width != 0))
|
||||
{
|
||||
slot = BufferSlotArray.InvalidBufferSlot;
|
||||
slot = BufferSlotArray.InvalidBufferSlot;
|
||||
fence = AndroidFence.NoFence;
|
||||
|
||||
return Status.BadValue;
|
||||
|
@ -157,7 +159,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
if (status != Status.Success)
|
||||
{
|
||||
slot = BufferSlotArray.InvalidBufferSlot;
|
||||
slot = BufferSlotArray.InvalidBufferSlot;
|
||||
fence = AndroidFence.NoFence;
|
||||
|
||||
return status;
|
||||
|
@ -176,7 +178,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
if (width == 0 || height == 0)
|
||||
{
|
||||
width = (uint)Core.DefaultWidth;
|
||||
width = (uint)Core.DefaultWidth;
|
||||
height = (uint)Core.DefaultHeight;
|
||||
}
|
||||
|
||||
|
@ -190,7 +192,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
{
|
||||
if (!Core.Slots[slot].IsPreallocated)
|
||||
{
|
||||
slot = BufferSlotArray.InvalidBufferSlot;
|
||||
slot = BufferSlotArray.InvalidBufferSlot;
|
||||
fence = AndroidFence.NoFence;
|
||||
|
||||
return Status.NoMemory;
|
||||
|
@ -202,7 +204,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
$"available: Width = {graphicBuffer.Width} Height = {graphicBuffer.Height} Format = {graphicBuffer.Format} Usage = {graphicBuffer.Usage:x} " +
|
||||
$"requested: Width = {width} Height = {height} Format = {format} Usage = {usage:x}");
|
||||
|
||||
slot = BufferSlotArray.InvalidBufferSlot;
|
||||
slot = BufferSlotArray.InvalidBufferSlot;
|
||||
fence = AndroidFence.NoFence;
|
||||
|
||||
return Status.NoInit;
|
||||
|
@ -215,8 +217,8 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
fence = Core.Slots[slot].Fence;
|
||||
|
||||
Core.Slots[slot].Fence = AndroidFence.NoFence;
|
||||
Core.Slots[slot].QueueTime = TimeSpanType.Zero;
|
||||
Core.Slots[slot].Fence = AndroidFence.NoFence;
|
||||
Core.Slots[slot].QueueTime = TimeSpanType.Zero;
|
||||
Core.Slots[slot].PresentationTime = TimeSpanType.Zero;
|
||||
|
||||
Core.CheckSystemEventsLocked(Core.GetMaxBufferCountLocked(async));
|
||||
|
@ -267,7 +269,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
if (Core.IsAbandoned)
|
||||
{
|
||||
graphicBuffer = default;
|
||||
fence = AndroidFence.NoFence;
|
||||
fence = AndroidFence.NoFence;
|
||||
|
||||
return Status.NoInit;
|
||||
}
|
||||
|
@ -288,13 +290,13 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
if (nextBufferSlot == BufferSlotArray.InvalidBufferSlot)
|
||||
{
|
||||
graphicBuffer = default;
|
||||
fence = AndroidFence.NoFence;
|
||||
fence = AndroidFence.NoFence;
|
||||
|
||||
return Status.NoMemory;
|
||||
}
|
||||
|
||||
graphicBuffer = Core.Slots[nextBufferSlot].GraphicBuffer;
|
||||
fence = Core.Slots[nextBufferSlot].Fence;
|
||||
fence = Core.Slots[nextBufferSlot].Fence;
|
||||
|
||||
Core.FreeBufferLocked(nextBufferSlot);
|
||||
|
||||
|
@ -326,8 +328,8 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
Core.Slots[slot].GraphicBuffer.Set(graphicBuffer);
|
||||
|
||||
Core.Slots[slot].BufferState = BufferState.Dequeued;
|
||||
Core.Slots[slot].Fence = AndroidFence.NoFence;
|
||||
Core.Slots[slot].BufferState = BufferState.Dequeued;
|
||||
Core.Slots[slot].Fence = AndroidFence.NoFence;
|
||||
Core.Slots[slot].RequestBufferCalled = true;
|
||||
|
||||
return returnFlags;
|
||||
|
@ -350,10 +352,10 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
return Status.BadValue;
|
||||
}
|
||||
|
||||
BufferItem item = new BufferItem();
|
||||
BufferItem item = new();
|
||||
|
||||
IConsumerListener frameAvailableListener = null;
|
||||
IConsumerListener frameReplaceListener = null;
|
||||
IConsumerListener frameReplaceListener = null;
|
||||
|
||||
lock (Core.Lock)
|
||||
{
|
||||
|
@ -388,25 +390,25 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
return Status.BadValue;
|
||||
}
|
||||
|
||||
Core.Slots[slot].Fence = input.Fence;
|
||||
Core.Slots[slot].Fence = input.Fence;
|
||||
Core.Slots[slot].BufferState = BufferState.Queued;
|
||||
Core.FrameCounter++;
|
||||
Core.Slots[slot].FrameNumber = Core.FrameCounter;
|
||||
Core.Slots[slot].QueueTime = TimeSpanType.FromTimeSpan(_tickSource.ElapsedTime);
|
||||
Core.Slots[slot].FrameNumber = Core.FrameCounter;
|
||||
Core.Slots[slot].QueueTime = TimeSpanType.FromTimeSpan(_tickSource.ElapsedTime);
|
||||
Core.Slots[slot].PresentationTime = TimeSpanType.Zero;
|
||||
|
||||
item.AcquireCalled = Core.Slots[slot].AcquireCalled;
|
||||
item.Crop = input.Crop;
|
||||
item.Transform = input.Transform;
|
||||
item.AcquireCalled = Core.Slots[slot].AcquireCalled;
|
||||
item.Crop = input.Crop;
|
||||
item.Transform = input.Transform;
|
||||
item.TransformToDisplayInverse = (input.Transform & NativeWindowTransform.InverseDisplay) == NativeWindowTransform.InverseDisplay;
|
||||
item.ScalingMode = input.ScalingMode;
|
||||
item.Timestamp = input.Timestamp;
|
||||
item.IsAutoTimestamp = input.IsAutoTimestamp != 0;
|
||||
item.SwapInterval = input.SwapInterval;
|
||||
item.FrameNumber = Core.FrameCounter;
|
||||
item.Slot = slot;
|
||||
item.Fence = input.Fence;
|
||||
item.IsDroppable = Core.DequeueBufferCannotBlock || input.Async != 0;
|
||||
item.ScalingMode = input.ScalingMode;
|
||||
item.Timestamp = input.Timestamp;
|
||||
item.IsAutoTimestamp = input.IsAutoTimestamp != 0;
|
||||
item.SwapInterval = input.SwapInterval;
|
||||
item.FrameNumber = Core.FrameCounter;
|
||||
item.Slot = slot;
|
||||
item.Fence = input.Fence;
|
||||
item.IsDroppable = Core.DequeueBufferCannotBlock || input.Async != 0;
|
||||
|
||||
item.GraphicBuffer.Set(Core.Slots[slot].GraphicBuffer);
|
||||
item.GraphicBuffer.Object.IncrementNvMapHandleRefCount(Core.Owner);
|
||||
|
@ -416,8 +418,8 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
Core.BufferHistory[Core.BufferHistoryPosition] = new BufferInfo
|
||||
{
|
||||
FrameNumber = Core.FrameCounter,
|
||||
QueueTime = Core.Slots[slot].QueueTime,
|
||||
State = BufferState.Queued
|
||||
QueueTime = Core.Slots[slot].QueueTime,
|
||||
State = BufferState.Queued,
|
||||
};
|
||||
|
||||
_stickyTransform = input.StickyTransform;
|
||||
|
@ -460,10 +462,10 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
output = new QueueBufferOutput
|
||||
{
|
||||
Width = (uint)Core.DefaultWidth,
|
||||
Height = (uint)Core.DefaultHeight,
|
||||
TransformHint = Core.TransformHint,
|
||||
NumPendingBuffers = (uint)Core.Queue.Count
|
||||
Width = (uint)Core.DefaultWidth,
|
||||
Height = (uint)Core.DefaultHeight,
|
||||
TransformHint = Core.TransformHint,
|
||||
NumPendingBuffers = (uint)Core.Queue.Count,
|
||||
};
|
||||
|
||||
if ((input.StickyTransform & 8) != 0)
|
||||
|
@ -506,7 +508,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
Core.Slots[slot].BufferState = BufferState.Free;
|
||||
Core.Slots[slot].FrameNumber = 0;
|
||||
Core.Slots[slot].Fence = fence;
|
||||
Core.Slots[slot].Fence = fence;
|
||||
Core.SignalDequeueEvent();
|
||||
Core.SignalWaitBufferFreeEvent();
|
||||
}
|
||||
|
@ -568,7 +570,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
return Status.BadValue;
|
||||
}
|
||||
|
||||
Core.BufferHasBeenQueued = false;
|
||||
Core.BufferHasBeenQueued = false;
|
||||
Core.DequeueBufferCannotBlock = Core.ConsumerControlledByApp && producerControlledByApp;
|
||||
|
||||
switch (api)
|
||||
|
@ -578,11 +580,11 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
case NativeWindowApi.Media:
|
||||
case NativeWindowApi.Camera:
|
||||
Core.ProducerListener = listener;
|
||||
Core.ConnectedApi = api;
|
||||
Core.ConnectedApi = api;
|
||||
|
||||
output.Width = (uint)Core.DefaultWidth;
|
||||
output.Height = (uint)Core.DefaultHeight;
|
||||
output.TransformHint = Core.TransformHint;
|
||||
output.Width = (uint)Core.DefaultWidth;
|
||||
output.Height = (uint)Core.DefaultHeight;
|
||||
output.TransformHint = Core.TransformHint;
|
||||
output.NumPendingBuffers = (uint)Core.Queue.Count;
|
||||
|
||||
if (NxSettings.Settings.TryGetValue("nv!nvn_no_vsync_capability", out object noVSyncCapability) && (bool)noVSyncCapability)
|
||||
|
@ -627,7 +629,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
producerListener = Core.ProducerListener;
|
||||
|
||||
Core.ProducerListener = null;
|
||||
Core.ConnectedApi = NativeWindowApi.NoApi;
|
||||
Core.ConnectedApi = NativeWindowApi.NoApi;
|
||||
|
||||
Core.SignalWaitBufferFreeEvent();
|
||||
Core.SignalFrameAvailableEvent();
|
||||
|
@ -667,13 +669,13 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
lock (Core.Lock)
|
||||
{
|
||||
Core.Slots[slot].BufferState = BufferState.Free;
|
||||
Core.Slots[slot].Fence = AndroidFence.NoFence;
|
||||
Core.Slots[slot].RequestBufferCalled = false;
|
||||
Core.Slots[slot].AcquireCalled = false;
|
||||
Core.Slots[slot].BufferState = BufferState.Free;
|
||||
Core.Slots[slot].Fence = AndroidFence.NoFence;
|
||||
Core.Slots[slot].RequestBufferCalled = false;
|
||||
Core.Slots[slot].AcquireCalled = false;
|
||||
Core.Slots[slot].NeedsCleanupOnRelease = false;
|
||||
Core.Slots[slot].IsPreallocated = !graphicBuffer.IsNull;
|
||||
Core.Slots[slot].FrameNumber = 0;
|
||||
Core.Slots[slot].IsPreallocated = !graphicBuffer.IsNull;
|
||||
Core.Slots[slot].FrameNumber = 0;
|
||||
|
||||
Core.Slots[slot].GraphicBuffer.Set(graphicBuffer);
|
||||
|
||||
|
@ -689,8 +691,8 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
{
|
||||
// NOTE: Nintendo set the default width, height and format from the GraphicBuffer..
|
||||
// This is entirely wrong and should only be controlled by the consumer...
|
||||
Core.DefaultWidth = graphicBuffer.Object.Width;
|
||||
Core.DefaultHeight = graphicBuffer.Object.Height;
|
||||
Core.DefaultWidth = graphicBuffer.Object.Width;
|
||||
Core.DefaultHeight = graphicBuffer.Object.Height;
|
||||
Core.DefaultBufferFormat = graphicBuffer.Object.Format;
|
||||
}
|
||||
else
|
||||
|
@ -729,7 +731,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
{
|
||||
bool tryAgain = true;
|
||||
|
||||
freeSlot = BufferSlotArray.InvalidBufferSlot;
|
||||
freeSlot = BufferSlotArray.InvalidBufferSlot;
|
||||
returnStatus = Status.Success;
|
||||
|
||||
while (tryAgain)
|
||||
|
|
|
@ -6,24 +6,24 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
class BufferSlot
|
||||
{
|
||||
public AndroidStrongPointer<GraphicBuffer> GraphicBuffer;
|
||||
public BufferState BufferState;
|
||||
public bool RequestBufferCalled;
|
||||
public ulong FrameNumber;
|
||||
public AndroidFence Fence;
|
||||
public bool AcquireCalled;
|
||||
public bool NeedsCleanupOnRelease;
|
||||
public bool AttachedByConsumer;
|
||||
public TimeSpanType QueueTime;
|
||||
public TimeSpanType PresentationTime;
|
||||
public bool IsPreallocated;
|
||||
public BufferState BufferState;
|
||||
public bool RequestBufferCalled;
|
||||
public ulong FrameNumber;
|
||||
public AndroidFence Fence;
|
||||
public bool AcquireCalled;
|
||||
public bool NeedsCleanupOnRelease;
|
||||
public bool AttachedByConsumer;
|
||||
public TimeSpanType QueueTime;
|
||||
public TimeSpanType PresentationTime;
|
||||
public bool IsPreallocated;
|
||||
|
||||
public BufferSlot()
|
||||
{
|
||||
GraphicBuffer = new AndroidStrongPointer<GraphicBuffer>();
|
||||
BufferState = BufferState.Free;
|
||||
QueueTime = TimeSpanType.Zero;
|
||||
GraphicBuffer = new AndroidStrongPointer<GraphicBuffer>();
|
||||
BufferState = BufferState.Free;
|
||||
QueueTime = TimeSpanType.Zero;
|
||||
PresentationTime = TimeSpanType.Zero;
|
||||
IsPreallocated = false;
|
||||
IsPreallocated = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
class BufferSlotArray
|
||||
{
|
||||
// TODO: move to BufferQueue
|
||||
public const int NumBufferSlots = 0x40;
|
||||
public const int NumBufferSlots = 0x40;
|
||||
public const int MaxAcquiredBuffers = NumBufferSlots - 2;
|
||||
public const int InvalidBufferSlot = -1;
|
||||
public const int InvalidBufferSlot = -1;
|
||||
|
||||
private BufferSlot[] _raw = new BufferSlot[NumBufferSlots];
|
||||
private readonly BufferSlot[] _raw = new BufferSlot[NumBufferSlots];
|
||||
|
||||
public BufferSlotArray()
|
||||
{
|
||||
|
|
|
@ -8,8 +8,8 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
public class Slot
|
||||
{
|
||||
public AndroidStrongPointer<GraphicBuffer> GraphicBuffer;
|
||||
public AndroidFence Fence;
|
||||
public ulong FrameNumber;
|
||||
public AndroidFence Fence;
|
||||
public ulong FrameNumber;
|
||||
|
||||
public Slot()
|
||||
{
|
||||
|
@ -25,7 +25,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
protected readonly object Lock = new();
|
||||
|
||||
private IConsumerListener _listener;
|
||||
private readonly IConsumerListener _listener;
|
||||
|
||||
public ConsumerBase(BufferQueueConsumer consumer, bool controlledByApp, IConsumerListener listener)
|
||||
{
|
||||
|
@ -35,8 +35,8 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
}
|
||||
|
||||
IsAbandoned = false;
|
||||
Consumer = consumer;
|
||||
_listener = listener;
|
||||
Consumer = consumer;
|
||||
_listener = listener;
|
||||
|
||||
Status connectStatus = consumer.Connect(this, controlledByApp);
|
||||
|
||||
|
@ -81,7 +81,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
{
|
||||
Slots[slotIndex].GraphicBuffer.Reset();
|
||||
|
||||
Slots[slotIndex].Fence = AndroidFence.NoFence;
|
||||
Slots[slotIndex].Fence = AndroidFence.NoFence;
|
||||
Slots[slotIndex].FrameNumber = 0;
|
||||
}
|
||||
|
||||
|
@ -123,7 +123,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
}
|
||||
|
||||
Slots[bufferItem.Slot].FrameNumber = bufferItem.FrameNumber;
|
||||
Slots[bufferItem.Slot].Fence = bufferItem.Fence;
|
||||
Slots[bufferItem.Slot].Fence = bufferItem.Fence;
|
||||
|
||||
return Status.Success;
|
||||
}
|
||||
|
|
|
@ -7,11 +7,11 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
{
|
||||
class HOSBinderDriverServer : IHOSBinderDriver
|
||||
{
|
||||
private static Dictionary<int, IBinder> _registeredBinderObjects = new Dictionary<int, IBinder>();
|
||||
private static readonly Dictionary<int, IBinder> _registeredBinderObjects = new();
|
||||
|
||||
private static int _lastBinderId = 0;
|
||||
|
||||
private static object _lock = new object();
|
||||
private static readonly object _lock = new();
|
||||
|
||||
public static int RegisterBinderObject(IBinder binder)
|
||||
{
|
||||
|
|
|
@ -13,10 +13,10 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
ResultCode OnTransact(uint code, uint flags, ReadOnlySpan<byte> inputParcel, Span<byte> outputParcel)
|
||||
{
|
||||
Parcel inputParcelReader = new Parcel(inputParcel.ToArray());
|
||||
Parcel inputParcelReader = new(inputParcel.ToArray());
|
||||
|
||||
// TODO: support objects?
|
||||
Parcel outputParcelWriter = new Parcel((uint)(outputParcel.Length - Unsafe.SizeOf<ParcelHeader>()), 0);
|
||||
Parcel outputParcelWriter = new((uint)(outputParcel.Length - Unsafe.SizeOf<ParcelHeader>()), 0);
|
||||
|
||||
string inputInterfaceToken = inputParcelReader.ReadInterfaceToken();
|
||||
|
||||
|
|
|
@ -29,33 +29,33 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
SetPreallocatedBuffer,
|
||||
Reserved15,
|
||||
GetBufferInfo,
|
||||
GetBufferHistory
|
||||
GetBufferHistory,
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1, Size = 0x54)]
|
||||
public struct QueueBufferInput : IFlattenable
|
||||
{
|
||||
public long Timestamp;
|
||||
public int IsAutoTimestamp;
|
||||
public Rect Crop;
|
||||
public long Timestamp;
|
||||
public int IsAutoTimestamp;
|
||||
public Rect Crop;
|
||||
public NativeWindowScalingMode ScalingMode;
|
||||
public NativeWindowTransform Transform;
|
||||
public uint StickyTransform;
|
||||
public int Async;
|
||||
public int SwapInterval;
|
||||
public AndroidFence Fence;
|
||||
public NativeWindowTransform Transform;
|
||||
public uint StickyTransform;
|
||||
public int Async;
|
||||
public int SwapInterval;
|
||||
public AndroidFence Fence;
|
||||
|
||||
public void Flatten(Parcel parcel)
|
||||
{
|
||||
parcel.WriteUnmanagedType(ref this);
|
||||
}
|
||||
|
||||
public uint GetFdCount()
|
||||
public readonly uint GetFdCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public uint GetFlattenedSize()
|
||||
public readonly uint GetFlattenedSize()
|
||||
{
|
||||
return (uint)Unsafe.SizeOf<QueueBufferInput>();
|
||||
}
|
||||
|
@ -68,11 +68,11 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
public struct QueueBufferOutput
|
||||
{
|
||||
public uint Width;
|
||||
public uint Height;
|
||||
public uint Width;
|
||||
public uint Height;
|
||||
public NativeWindowTransform TransformHint;
|
||||
public uint NumPendingBuffers;
|
||||
public ulong FrameNumber;
|
||||
public uint NumPendingBuffers;
|
||||
public ulong FrameNumber;
|
||||
|
||||
public void WriteToParcel(Parcel parcel)
|
||||
{
|
||||
|
@ -108,15 +108,15 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
public void OnTransact(uint code, uint flags, Parcel inputParcel, Parcel outputParcel)
|
||||
{
|
||||
Status status = Status.Success;
|
||||
int slot;
|
||||
AndroidFence fence;
|
||||
QueueBufferInput queueInput;
|
||||
Status status = Status.Success;
|
||||
int slot;
|
||||
AndroidFence fence;
|
||||
QueueBufferInput queueInput;
|
||||
QueueBufferOutput queueOutput;
|
||||
NativeWindowApi api;
|
||||
NativeWindowApi api;
|
||||
|
||||
AndroidStrongPointer<GraphicBuffer> graphicBuffer;
|
||||
AndroidStrongPointer<AndroidFence> strongFence;
|
||||
AndroidStrongPointer<AndroidFence> strongFence;
|
||||
|
||||
switch ((TransactionCode)code)
|
||||
{
|
||||
|
@ -139,13 +139,13 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
break;
|
||||
case TransactionCode.DequeueBuffer:
|
||||
bool async = inputParcel.ReadBoolean();
|
||||
uint width = inputParcel.ReadUInt32();
|
||||
uint height = inputParcel.ReadUInt32();
|
||||
bool async = inputParcel.ReadBoolean();
|
||||
uint width = inputParcel.ReadUInt32();
|
||||
uint height = inputParcel.ReadUInt32();
|
||||
PixelFormat format = inputParcel.ReadUnmanagedType<PixelFormat>();
|
||||
uint usage = inputParcel.ReadUInt32();
|
||||
uint usage = inputParcel.ReadUInt32();
|
||||
|
||||
status = DequeueBuffer(out int dequeueSlot, out fence, async, width, height, format, usage);
|
||||
status = DequeueBuffer(out int dequeueSlot, out fence, async, width, height, format, usage);
|
||||
strongFence = new AndroidStrongPointer<AndroidFence>(fence);
|
||||
|
||||
outputParcel.WriteInt32(dequeueSlot);
|
||||
|
@ -163,7 +163,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
break;
|
||||
case TransactionCode.DetachNextBuffer:
|
||||
status = DetachNextBuffer(out graphicBuffer, out fence);
|
||||
status = DetachNextBuffer(out graphicBuffer, out fence);
|
||||
strongFence = new AndroidStrongPointer<AndroidFence>(fence);
|
||||
|
||||
outputParcel.WriteStrongPointer(ref graphicBuffer);
|
||||
|
@ -183,7 +183,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
break;
|
||||
case TransactionCode.QueueBuffer:
|
||||
slot = inputParcel.ReadInt32();
|
||||
slot = inputParcel.ReadInt32();
|
||||
queueInput = inputParcel.ReadFlattenable<QueueBufferInput>();
|
||||
|
||||
status = QueueBuffer(slot, ref queueInput, out queueOutput);
|
||||
|
@ -194,7 +194,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
break;
|
||||
case TransactionCode.CancelBuffer:
|
||||
slot = inputParcel.ReadInt32();
|
||||
slot = inputParcel.ReadInt32();
|
||||
fence = inputParcel.ReadFlattenable<AndroidFence>();
|
||||
|
||||
CancelBuffer(slot, ref fence);
|
||||
|
|
|
@ -17,18 +17,18 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
{
|
||||
int binderId = context.RequestData.ReadInt32();
|
||||
|
||||
uint code = context.RequestData.ReadUInt32();
|
||||
uint code = context.RequestData.ReadUInt32();
|
||||
uint flags = context.RequestData.ReadUInt32();
|
||||
|
||||
ulong dataPos = context.Request.SendBuff[0].Position;
|
||||
ulong dataPos = context.Request.SendBuff[0].Position;
|
||||
ulong dataSize = context.Request.SendBuff[0].Size;
|
||||
|
||||
ulong replyPos = context.Request.ReceiveBuff[0].Position;
|
||||
ulong replyPos = context.Request.ReceiveBuff[0].Position;
|
||||
ulong replySize = context.Request.ReceiveBuff[0].Size;
|
||||
|
||||
ReadOnlySpan<byte> inputParcel = context.Memory.GetSpan(dataPos, (int)dataSize);
|
||||
|
||||
Span<byte> outputParcel = new Span<byte>(new byte[replySize]);
|
||||
Span<byte> outputParcel = new(new byte[replySize]);
|
||||
|
||||
ResultCode result = OnTransact(binderId, code, flags, inputParcel, outputParcel);
|
||||
|
||||
|
@ -45,8 +45,8 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
public ResultCode AdjustRefcount(ServiceCtx context)
|
||||
{
|
||||
int binderId = context.RequestData.ReadInt32();
|
||||
int addVal = context.RequestData.ReadInt32();
|
||||
int type = context.RequestData.ReadInt32();
|
||||
int addVal = context.RequestData.ReadInt32();
|
||||
int type = context.RequestData.ReadInt32();
|
||||
|
||||
return AdjustRefcount(binderId, addVal, type);
|
||||
}
|
||||
|
@ -77,27 +77,26 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
{
|
||||
int binderId = context.RequestData.ReadInt32();
|
||||
|
||||
uint code = context.RequestData.ReadUInt32();
|
||||
uint code = context.RequestData.ReadUInt32();
|
||||
uint flags = context.RequestData.ReadUInt32();
|
||||
|
||||
(ulong dataPos, ulong dataSize) = context.Request.GetBufferType0x21();
|
||||
(ulong dataPos, ulong dataSize) = context.Request.GetBufferType0x21();
|
||||
(ulong replyPos, ulong replySize) = context.Request.GetBufferType0x22();
|
||||
|
||||
ReadOnlySpan<byte> inputParcel = context.Memory.GetSpan(dataPos, (int)dataSize);
|
||||
|
||||
using (IMemoryOwner<byte> outputParcelOwner = ByteMemoryPool.RentCleared(replySize))
|
||||
using IMemoryOwner<byte> outputParcelOwner = ByteMemoryPool.RentCleared(replySize);
|
||||
|
||||
Span<byte> outputParcel = outputParcelOwner.Memory.Span;
|
||||
|
||||
ResultCode result = OnTransact(binderId, code, flags, inputParcel, outputParcel);
|
||||
|
||||
if (result == ResultCode.Success)
|
||||
{
|
||||
Span<byte> outputParcel = outputParcelOwner.Memory.Span;
|
||||
|
||||
ResultCode result = OnTransact(binderId, code, flags, inputParcel, outputParcel);
|
||||
|
||||
if (result == ResultCode.Success)
|
||||
{
|
||||
context.Memory.Write(replyPos, outputParcel);
|
||||
}
|
||||
|
||||
return result;
|
||||
context.Memory.Write(replyPos, outputParcel);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected abstract ResultCode AdjustRefcount(int binderId, int addVal, int type);
|
||||
|
|
|
@ -5,6 +5,6 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
NotInitialized,
|
||||
ManagedClosed,
|
||||
ManagedOpened,
|
||||
Stray
|
||||
Stray,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
{
|
||||
enum NativeWindowApi
|
||||
{
|
||||
NoApi = 0,
|
||||
NVN = 1,
|
||||
CPU = 2,
|
||||
Media = 3,
|
||||
Camera = 4
|
||||
NoApi = 0,
|
||||
NVN = 1,
|
||||
CPU = 2,
|
||||
Media = 3,
|
||||
Camera = 4,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
{
|
||||
enum NativeWindowAttribute : uint
|
||||
{
|
||||
Width = 0,
|
||||
Height = 1,
|
||||
Format = 2,
|
||||
MinUnqueuedBuffers = 3,
|
||||
Width = 0,
|
||||
Height = 1,
|
||||
Format = 2,
|
||||
MinUnqueuedBuffers = 3,
|
||||
ConsumerRunningBehind = 9,
|
||||
ConsumerUsageBits = 10,
|
||||
MaxBufferCountAsync = 12
|
||||
ConsumerUsageBits = 10,
|
||||
MaxBufferCountAsync = 12,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
{
|
||||
enum NativeWindowScalingMode : uint
|
||||
{
|
||||
Freeze = 0,
|
||||
Freeze = 0,
|
||||
ScaleToWindow = 1,
|
||||
ScaleCrop = 2,
|
||||
Unknown = 3,
|
||||
NoScaleCrop = 4,
|
||||
ScaleCrop = 2,
|
||||
Unknown = 3,
|
||||
NoScaleCrop = 4,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,14 +5,14 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
[Flags]
|
||||
enum NativeWindowTransform : uint
|
||||
{
|
||||
None = 0,
|
||||
FlipX = 1,
|
||||
FlipY = 2,
|
||||
Rotate90 = 4,
|
||||
Rotate180 = FlipX | FlipY,
|
||||
Rotate270 = Rotate90 | Rotate180,
|
||||
InverseDisplay = 8,
|
||||
None = 0,
|
||||
FlipX = 1,
|
||||
FlipY = 2,
|
||||
Rotate90 = 4,
|
||||
Rotate180 = FlipX | FlipY,
|
||||
Rotate270 = Rotate90 | Rotate180,
|
||||
InverseDisplay = 8,
|
||||
NoVSyncCapability = 0x10,
|
||||
ReturnFrameNumber = 0x20
|
||||
ReturnFrameNumber = 0x20,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
{
|
||||
private readonly byte[] _rawData;
|
||||
|
||||
private Span<byte> Raw => new Span<byte>(_rawData);
|
||||
private Span<byte> Raw => new(_rawData);
|
||||
|
||||
private ref ParcelHeader Header => ref MemoryMarshal.Cast<byte, ParcelHeader>(_rawData)[0];
|
||||
|
||||
|
@ -26,10 +26,10 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
public Parcel(byte[] rawData)
|
||||
{
|
||||
_rawData = rawData;
|
||||
_rawData = rawData;
|
||||
|
||||
_payloadPosition = 0;
|
||||
_objectPosition = 0;
|
||||
_objectPosition = 0;
|
||||
}
|
||||
|
||||
public Parcel(uint payloadSize, uint objectsSize)
|
||||
|
@ -38,16 +38,18 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
_rawData = new byte[BitUtils.AlignUp<uint>(headerSize + payloadSize + objectsSize, 4)];
|
||||
|
||||
Header.PayloadSize = payloadSize;
|
||||
Header.ObjectsSize = objectsSize;
|
||||
Header.PayloadSize = payloadSize;
|
||||
Header.ObjectsSize = objectsSize;
|
||||
Header.PayloadOffset = headerSize;
|
||||
Header.ObjectOffset = Header.PayloadOffset + Header.ObjectsSize;
|
||||
Header.ObjectOffset = Header.PayloadOffset + Header.ObjectsSize;
|
||||
}
|
||||
|
||||
public string ReadInterfaceToken()
|
||||
{
|
||||
// Ignore the policy flags
|
||||
#pragma warning disable IDE0059 // Remove unnecessary value assignment
|
||||
int strictPolicy = ReadInt32();
|
||||
#pragma warning restore IDE0059
|
||||
|
||||
return ReadString16();
|
||||
}
|
||||
|
@ -64,7 +66,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
ReadOnlySpan<byte> data = ReadInPlace((size + 1) * 2);
|
||||
|
||||
// Return the unicode string without the last character (null terminator)
|
||||
return Encoding.Unicode.GetString(data.Slice(0, size * 2));
|
||||
return Encoding.Unicode.GetString(data[..(size * 2)]);
|
||||
}
|
||||
|
||||
public int ReadInt32() => ReadUnmanagedType<int>();
|
||||
|
@ -77,7 +79,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
{
|
||||
long flattenableSize = ReadInt64();
|
||||
|
||||
T result = new T();
|
||||
T result = new();
|
||||
|
||||
Debug.Assert(flattenableSize == result.GetFlattenedSize());
|
||||
|
||||
|
@ -86,7 +88,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
return result;
|
||||
}
|
||||
|
||||
public T ReadUnmanagedType<T>() where T: unmanaged
|
||||
public T ReadUnmanagedType<T>() where T : unmanaged
|
||||
{
|
||||
ReadOnlySpan<byte> data = ReadInPlace(Unsafe.SizeOf<T>());
|
||||
|
||||
|
@ -105,8 +107,8 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
[StructLayout(LayoutKind.Sequential, Size = 0x28)]
|
||||
private struct FlatBinderObject
|
||||
{
|
||||
public int Type;
|
||||
public int Flags;
|
||||
public int Type;
|
||||
public int Flags;
|
||||
public long BinderId;
|
||||
public long Cookie;
|
||||
|
||||
|
@ -115,12 +117,12 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
public Span<byte> ServiceName => MemoryMarshal.CreateSpan(ref _serviceNameStart, 0x8);
|
||||
}
|
||||
|
||||
public void WriteObject<T>(T obj, string serviceName) where T: IBinder
|
||||
public void WriteObject<T>(T obj, string serviceName) where T : IBinder
|
||||
{
|
||||
FlatBinderObject flatBinderObject = new FlatBinderObject
|
||||
FlatBinderObject flatBinderObject = new()
|
||||
{
|
||||
Type = 2,
|
||||
Flags = 0,
|
||||
Type = 2,
|
||||
Flags = 0,
|
||||
BinderId = HOSBinderDriverServer.GetBinderId(obj),
|
||||
};
|
||||
|
||||
|
@ -149,7 +151,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
}
|
||||
}
|
||||
|
||||
public void WriteStrongPointer<T>(ref AndroidStrongPointer<T> value) where T: unmanaged, IFlattenable
|
||||
public void WriteStrongPointer<T>(ref AndroidStrongPointer<T> value) where T : unmanaged, IFlattenable
|
||||
{
|
||||
WriteBoolean(!value.IsNull);
|
||||
|
||||
|
@ -205,17 +207,17 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
{
|
||||
uint headerSize = (uint)Unsafe.SizeOf<ParcelHeader>();
|
||||
|
||||
Header.PayloadSize = (uint)_payloadPosition;
|
||||
Header.ObjectsSize = (uint)_objectPosition;
|
||||
Header.PayloadSize = (uint)_payloadPosition;
|
||||
Header.ObjectsSize = (uint)_objectPosition;
|
||||
Header.PayloadOffset = headerSize;
|
||||
Header.ObjectOffset = Header.PayloadOffset + Header.PayloadSize;
|
||||
Header.ObjectOffset = Header.PayloadOffset + Header.PayloadSize;
|
||||
}
|
||||
|
||||
public ReadOnlySpan<byte> Finish()
|
||||
{
|
||||
UpdateHeader();
|
||||
|
||||
return Raw.Slice(0, (int)(Header.PayloadSize + Header.ObjectsSize + Unsafe.SizeOf<ParcelHeader>()));
|
||||
return Raw[..(int)(Header.PayloadSize + Header.ObjectsSize + Unsafe.SizeOf<ParcelHeader>())];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +1,25 @@
|
|||
namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
||||
{
|
||||
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
|
||||
enum Status
|
||||
{
|
||||
Success = 0,
|
||||
WouldBlock = -11,
|
||||
NoMemory = -12,
|
||||
Busy = -16,
|
||||
NoInit = -19,
|
||||
BadValue = -22,
|
||||
Success = 0,
|
||||
WouldBlock = -11,
|
||||
NoMemory = -12,
|
||||
Busy = -16,
|
||||
NoInit = -19,
|
||||
BadValue = -22,
|
||||
InvalidOperation = -37,
|
||||
|
||||
// Producer flags
|
||||
BufferNeedsReallocation = 1,
|
||||
ReleaseAllBuffers = 2,
|
||||
ReleaseAllBuffers = 2,
|
||||
|
||||
// Consumer errors
|
||||
StaleBufferSlot = 1,
|
||||
StaleBufferSlot = 1,
|
||||
NoBufferAvailaible = 2,
|
||||
PresentLater = 3,
|
||||
PresentLater = 3,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,49 +11,47 @@ using System.Threading;
|
|||
|
||||
namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
||||
{
|
||||
using ResultCode = Ryujinx.HLE.HOS.Services.Vi.ResultCode;
|
||||
|
||||
class SurfaceFlinger : IConsumerListener, IDisposable
|
||||
{
|
||||
private const int TargetFps = 60;
|
||||
|
||||
private Switch _device;
|
||||
private readonly Switch _device;
|
||||
|
||||
private Dictionary<long, Layer> _layers;
|
||||
private readonly Dictionary<long, Layer> _layers;
|
||||
|
||||
private bool _isRunning;
|
||||
|
||||
private Thread _composerThread;
|
||||
private readonly Thread _composerThread;
|
||||
|
||||
private Stopwatch _chrono;
|
||||
private readonly Stopwatch _chrono;
|
||||
|
||||
private ManualResetEvent _event = new ManualResetEvent(false);
|
||||
private AutoResetEvent _nextFrameEvent = new AutoResetEvent(true);
|
||||
private readonly ManualResetEvent _event = new(false);
|
||||
private readonly AutoResetEvent _nextFrameEvent = new(true);
|
||||
private long _ticks;
|
||||
private long _ticksPerFrame;
|
||||
private long _spinTicks;
|
||||
private long _1msTicks;
|
||||
private readonly long _spinTicks;
|
||||
private readonly long _1msTicks;
|
||||
|
||||
private int _swapInterval;
|
||||
private int _swapIntervalDelay;
|
||||
|
||||
private readonly object Lock = new();
|
||||
private readonly object _lock = new();
|
||||
|
||||
public long RenderLayerId { get; private set; }
|
||||
|
||||
private class Layer
|
||||
{
|
||||
public int ProducerBinderId;
|
||||
public int ProducerBinderId;
|
||||
public IGraphicBufferProducer Producer;
|
||||
public BufferItemConsumer Consumer;
|
||||
public BufferQueueCore Core;
|
||||
public ulong Owner;
|
||||
public LayerState State;
|
||||
public BufferItemConsumer Consumer;
|
||||
public BufferQueueCore Core;
|
||||
public ulong Owner;
|
||||
public LayerState State;
|
||||
}
|
||||
|
||||
private class TextureCallbackInformation
|
||||
{
|
||||
public Layer Layer;
|
||||
public Layer Layer;
|
||||
public BufferItem Item;
|
||||
}
|
||||
|
||||
|
@ -65,7 +63,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
_composerThread = new Thread(HandleComposition)
|
||||
{
|
||||
Name = "SurfaceFlinger.Composer"
|
||||
Name = "SurfaceFlinger.Composer",
|
||||
};
|
||||
|
||||
_chrono = new Stopwatch();
|
||||
|
@ -100,7 +98,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
{
|
||||
layerId = 1;
|
||||
|
||||
lock (Lock)
|
||||
lock (_lock)
|
||||
{
|
||||
foreach (KeyValuePair<long, Layer> pair in _layers)
|
||||
{
|
||||
|
@ -118,7 +116,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
private void CreateLayerFromId(ulong pid, long layerId, LayerState initialState)
|
||||
{
|
||||
lock (Lock)
|
||||
lock (_lock)
|
||||
{
|
||||
Logger.Info?.Print(LogClass.SurfaceFlinger, $"Creating layer {layerId}");
|
||||
|
||||
|
@ -132,16 +130,16 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
_layers.Add(layerId, new Layer
|
||||
{
|
||||
ProducerBinderId = HOSBinderDriverServer.RegisterBinderObject(producer),
|
||||
Producer = producer,
|
||||
Consumer = new BufferItemConsumer(_device, consumer, 0, -1, false, this),
|
||||
Core = core,
|
||||
Owner = pid,
|
||||
State = initialState
|
||||
Producer = producer,
|
||||
Consumer = new BufferItemConsumer(_device, consumer, 0, -1, false, this),
|
||||
Core = core,
|
||||
Owner = pid,
|
||||
State = initialState,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public ResultCode OpenLayer(ulong pid, long layerId, out IBinder producer)
|
||||
public Vi.ResultCode OpenLayer(ulong pid, long layerId, out IBinder producer)
|
||||
{
|
||||
Layer layer = GetLayerByIdLocked(layerId);
|
||||
|
||||
|
@ -149,18 +147,18 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
{
|
||||
producer = null;
|
||||
|
||||
return ResultCode.InvalidArguments;
|
||||
return Vi.ResultCode.InvalidArguments;
|
||||
}
|
||||
|
||||
layer.State = LayerState.ManagedOpened;
|
||||
producer = layer.Producer;
|
||||
|
||||
return ResultCode.Success;
|
||||
return Vi.ResultCode.Success;
|
||||
}
|
||||
|
||||
public ResultCode CloseLayer(long layerId)
|
||||
public Vi.ResultCode CloseLayer(long layerId)
|
||||
{
|
||||
lock (Lock)
|
||||
lock (_lock)
|
||||
{
|
||||
Layer layer = GetLayerByIdLocked(layerId);
|
||||
|
||||
|
@ -168,18 +166,18 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
{
|
||||
Logger.Error?.Print(LogClass.SurfaceFlinger, $"Failed to close layer {layerId}");
|
||||
|
||||
return ResultCode.InvalidValue;
|
||||
return Vi.ResultCode.InvalidValue;
|
||||
}
|
||||
|
||||
CloseLayer(layerId, layer);
|
||||
|
||||
return ResultCode.Success;
|
||||
return Vi.ResultCode.Success;
|
||||
}
|
||||
}
|
||||
|
||||
public ResultCode DestroyManagedLayer(long layerId)
|
||||
public Vi.ResultCode DestroyManagedLayer(long layerId)
|
||||
{
|
||||
lock (Lock)
|
||||
lock (_lock)
|
||||
{
|
||||
Layer layer = GetLayerByIdLocked(layerId);
|
||||
|
||||
|
@ -187,14 +185,14 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
{
|
||||
Logger.Error?.Print(LogClass.SurfaceFlinger, $"Failed to destroy managed layer {layerId} (not found)");
|
||||
|
||||
return ResultCode.InvalidValue;
|
||||
return Vi.ResultCode.InvalidValue;
|
||||
}
|
||||
|
||||
if (layer.State != LayerState.ManagedClosed && layer.State != LayerState.ManagedOpened)
|
||||
{
|
||||
Logger.Error?.Print(LogClass.SurfaceFlinger, $"Failed to destroy managed layer {layerId} (permission denied)");
|
||||
|
||||
return ResultCode.PermissionDenied;
|
||||
return Vi.ResultCode.PermissionDenied;
|
||||
}
|
||||
|
||||
HOSBinderDriverServer.UnregisterBinderObject(layer.ProducerBinderId);
|
||||
|
@ -204,13 +202,13 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
CloseLayer(layerId, layer);
|
||||
}
|
||||
|
||||
return ResultCode.Success;
|
||||
return Vi.ResultCode.Success;
|
||||
}
|
||||
}
|
||||
|
||||
public ResultCode DestroyStrayLayer(long layerId)
|
||||
public Vi.ResultCode DestroyStrayLayer(long layerId)
|
||||
{
|
||||
lock (Lock)
|
||||
lock (_lock)
|
||||
{
|
||||
Layer layer = GetLayerByIdLocked(layerId);
|
||||
|
||||
|
@ -218,14 +216,14 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
{
|
||||
Logger.Error?.Print(LogClass.SurfaceFlinger, $"Failed to destroy stray layer {layerId} (not found)");
|
||||
|
||||
return ResultCode.InvalidValue;
|
||||
return Vi.ResultCode.InvalidValue;
|
||||
}
|
||||
|
||||
if (layer.State != LayerState.Stray)
|
||||
{
|
||||
Logger.Error?.Print(LogClass.SurfaceFlinger, $"Failed to destroy stray layer {layerId} (permission denied)");
|
||||
|
||||
return ResultCode.PermissionDenied;
|
||||
return Vi.ResultCode.PermissionDenied;
|
||||
}
|
||||
|
||||
HOSBinderDriverServer.UnregisterBinderObject(layer.ProducerBinderId);
|
||||
|
@ -235,7 +233,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
CloseLayer(layerId, layer);
|
||||
}
|
||||
|
||||
return ResultCode.Success;
|
||||
return Vi.ResultCode.Success;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -263,7 +261,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
public void SetRenderLayer(long layerId)
|
||||
{
|
||||
lock (Lock)
|
||||
lock (_lock)
|
||||
{
|
||||
RenderLayerId = layerId;
|
||||
}
|
||||
|
@ -284,7 +282,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
public IGraphicBufferProducer GetProducerByLayerId(long layerId)
|
||||
{
|
||||
lock (Lock)
|
||||
lock (_lock)
|
||||
{
|
||||
Layer layer = GetLayerByIdLocked(layerId);
|
||||
|
||||
|
@ -365,7 +363,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
public void Compose()
|
||||
{
|
||||
lock (Lock)
|
||||
lock (_lock)
|
||||
{
|
||||
// TODO: support multilayers (& multidisplay ?)
|
||||
if (RenderLayerId == 0)
|
||||
|
@ -403,7 +401,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
private void PostFrameBuffer(Layer layer, BufferItem item)
|
||||
{
|
||||
int frameBufferWidth = item.GraphicBuffer.Object.Width;
|
||||
int frameBufferWidth = item.GraphicBuffer.Object.Width;
|
||||
int frameBufferHeight = item.GraphicBuffer.Object.Height;
|
||||
|
||||
int nvMapHandle = item.GraphicBuffer.Object.Buffer.Surfaces[0].NvMapHandle;
|
||||
|
@ -434,9 +432,9 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
bool flipY = item.Transform.HasFlag(NativeWindowTransform.FlipY);
|
||||
|
||||
AspectRatio aspectRatio = _device.Configuration.AspectRatio;
|
||||
bool isStretched = aspectRatio == AspectRatio.Stretched;
|
||||
bool isStretched = aspectRatio == AspectRatio.Stretched;
|
||||
|
||||
ImageCrop crop = new ImageCrop(
|
||||
ImageCrop crop = new(
|
||||
cropRect.Left,
|
||||
cropRect.Right,
|
||||
cropRect.Top,
|
||||
|
@ -447,10 +445,10 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
aspectRatio.ToFloatX(),
|
||||
aspectRatio.ToFloatY());
|
||||
|
||||
TextureCallbackInformation textureCallbackInformation = new TextureCallbackInformation
|
||||
TextureCallbackInformation textureCallbackInformation = new()
|
||||
{
|
||||
Layer = layer,
|
||||
Item = item
|
||||
Item = item,
|
||||
};
|
||||
|
||||
if (_device.Gpu.Window.EnqueueFrameThreadSafe(
|
||||
|
@ -543,6 +541,6 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
_device.Statistics.RecordGameFrameTime();
|
||||
}
|
||||
|
||||
public void OnBuffersReleased() {}
|
||||
public void OnBuffersReleased() { }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,17 +16,17 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
private byte _fenceStorageStart;
|
||||
|
||||
private Span<byte> _storage => MemoryMarshal.CreateSpan(ref _fenceStorageStart, Unsafe.SizeOf<NvFence>() * 4);
|
||||
private Span<byte> Storage => MemoryMarshal.CreateSpan(ref _fenceStorageStart, Unsafe.SizeOf<NvFence>() * 4);
|
||||
|
||||
public Span<NvFence> NvFences => MemoryMarshal.Cast<byte, NvFence>(_storage);
|
||||
public Span<NvFence> NvFences => MemoryMarshal.Cast<byte, NvFence>(Storage);
|
||||
|
||||
public static AndroidFence NoFence
|
||||
{
|
||||
get
|
||||
{
|
||||
AndroidFence fence = new AndroidFence
|
||||
AndroidFence fence = new()
|
||||
{
|
||||
FenceCount = 0
|
||||
FenceCount = 0,
|
||||
};
|
||||
|
||||
fence.NvFences[0].Id = NvFence.InvalidSyncPointId;
|
||||
|
@ -81,12 +81,12 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
}
|
||||
}
|
||||
|
||||
public uint GetFlattenedSize()
|
||||
public readonly uint GetFlattenedSize()
|
||||
{
|
||||
return (uint)Unsafe.SizeOf<AndroidFence>();
|
||||
}
|
||||
|
||||
public uint GetFdCount()
|
||||
public readonly uint GetFdCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -101,4 +101,4 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
this = parcel.ReadUnmanagedType<AndroidFence>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger.Types
|
||||
{
|
||||
class AndroidStrongPointer<T> where T: unmanaged, IFlattenable
|
||||
class AndroidStrongPointer<T> where T : unmanaged, IFlattenable
|
||||
{
|
||||
public T Object;
|
||||
|
||||
|
@ -20,13 +20,13 @@
|
|||
|
||||
public void Set(AndroidStrongPointer<T> other)
|
||||
{
|
||||
Object = other.Object;
|
||||
Object = other.Object;
|
||||
_hasObject = other._hasObject;
|
||||
}
|
||||
|
||||
public void Set(T obj)
|
||||
{
|
||||
Object = obj;
|
||||
Object = obj;
|
||||
_hasObject = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,9 +6,9 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger.Types
|
|||
[StructLayout(LayoutKind.Sequential, Size = 0x1C, Pack = 1)]
|
||||
struct BufferInfo
|
||||
{
|
||||
public ulong FrameNumber;
|
||||
public ulong FrameNumber;
|
||||
public TimeSpanType QueueTime;
|
||||
public TimeSpanType PresentationTime;
|
||||
public BufferState State;
|
||||
public BufferState State;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,33 +6,33 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
class BufferItem : ICloneable
|
||||
{
|
||||
public AndroidStrongPointer<GraphicBuffer> GraphicBuffer;
|
||||
public AndroidFence Fence;
|
||||
public Rect Crop;
|
||||
public NativeWindowTransform Transform;
|
||||
public NativeWindowScalingMode ScalingMode;
|
||||
public long Timestamp;
|
||||
public bool IsAutoTimestamp;
|
||||
public int SwapInterval;
|
||||
public ulong FrameNumber;
|
||||
public int Slot;
|
||||
public bool IsDroppable;
|
||||
public bool AcquireCalled;
|
||||
public bool TransformToDisplayInverse;
|
||||
public AndroidFence Fence;
|
||||
public Rect Crop;
|
||||
public NativeWindowTransform Transform;
|
||||
public NativeWindowScalingMode ScalingMode;
|
||||
public long Timestamp;
|
||||
public bool IsAutoTimestamp;
|
||||
public int SwapInterval;
|
||||
public ulong FrameNumber;
|
||||
public int Slot;
|
||||
public bool IsDroppable;
|
||||
public bool AcquireCalled;
|
||||
public bool TransformToDisplayInverse;
|
||||
|
||||
public BufferItem()
|
||||
{
|
||||
GraphicBuffer = new AndroidStrongPointer<GraphicBuffer>();
|
||||
Transform = NativeWindowTransform.None;
|
||||
ScalingMode = NativeWindowScalingMode.Freeze;
|
||||
Timestamp = 0;
|
||||
IsAutoTimestamp = false;
|
||||
FrameNumber = 0;
|
||||
Slot = BufferSlotArray.InvalidBufferSlot;
|
||||
IsDroppable = false;
|
||||
AcquireCalled = false;
|
||||
GraphicBuffer = new AndroidStrongPointer<GraphicBuffer>();
|
||||
Transform = NativeWindowTransform.None;
|
||||
ScalingMode = NativeWindowScalingMode.Freeze;
|
||||
Timestamp = 0;
|
||||
IsAutoTimestamp = false;
|
||||
FrameNumber = 0;
|
||||
Slot = BufferSlotArray.InvalidBufferSlot;
|
||||
IsDroppable = false;
|
||||
AcquireCalled = false;
|
||||
TransformToDisplayInverse = false;
|
||||
SwapInterval = 1;
|
||||
Fence = AndroidFence.NoFence;
|
||||
SwapInterval = 1;
|
||||
Fence = AndroidFence.NoFence;
|
||||
|
||||
Crop = new Rect();
|
||||
Crop.MakeInvalid();
|
||||
|
@ -40,19 +40,20 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
public object Clone()
|
||||
{
|
||||
BufferItem item = new BufferItem();
|
||||
|
||||
item.Transform = Transform;
|
||||
item.ScalingMode = ScalingMode;
|
||||
item.IsAutoTimestamp = IsAutoTimestamp;
|
||||
item.FrameNumber = FrameNumber;
|
||||
item.Slot = Slot;
|
||||
item.IsDroppable = IsDroppable;
|
||||
item.AcquireCalled = AcquireCalled;
|
||||
item.TransformToDisplayInverse = TransformToDisplayInverse;
|
||||
item.SwapInterval = SwapInterval;
|
||||
item.Fence = Fence;
|
||||
item.Crop = Crop;
|
||||
BufferItem item = new()
|
||||
{
|
||||
Transform = Transform,
|
||||
ScalingMode = ScalingMode,
|
||||
IsAutoTimestamp = IsAutoTimestamp,
|
||||
FrameNumber = FrameNumber,
|
||||
Slot = Slot,
|
||||
IsDroppable = IsDroppable,
|
||||
AcquireCalled = AcquireCalled,
|
||||
TransformToDisplayInverse = TransformToDisplayInverse,
|
||||
SwapInterval = SwapInterval,
|
||||
Fence = Fence,
|
||||
Crop = Crop,
|
||||
};
|
||||
|
||||
item.GraphicBuffer.Set(GraphicBuffer);
|
||||
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
{
|
||||
internal enum BufferState
|
||||
{
|
||||
Free = 0,
|
||||
Free = 0,
|
||||
Dequeued = 1,
|
||||
Queued = 2,
|
||||
Acquired = 3
|
||||
Queued = 2,
|
||||
Acquired = 3,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,16 +2,16 @@
|
|||
{
|
||||
enum ColorBytePerPixel
|
||||
{
|
||||
Bpp1 = 1,
|
||||
Bpp2 = 2,
|
||||
Bpp4 = 4,
|
||||
Bpp8 = 8,
|
||||
Bpp16 = 16,
|
||||
Bpp24 = 24,
|
||||
Bpp32 = 32,
|
||||
Bpp48 = 48,
|
||||
Bpp64 = 64,
|
||||
Bpp96 = 96,
|
||||
Bpp128 = 128
|
||||
Bpp1 = 1,
|
||||
Bpp2 = 2,
|
||||
Bpp4 = 4,
|
||||
Bpp8 = 8,
|
||||
Bpp16 = 16,
|
||||
Bpp24 = 24,
|
||||
Bpp32 = 32,
|
||||
Bpp48 = 48,
|
||||
Bpp64 = 64,
|
||||
Bpp96 = 96,
|
||||
Bpp128 = 128,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
{
|
||||
enum ColorComponent : uint
|
||||
{
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
X1 = (0x01 << ColorShift.Component) | ColorBytePerPixel.Bpp1,
|
||||
X2 = (0x02 << ColorShift.Component) | ColorBytePerPixel.Bpp2,
|
||||
X4 = (0x03 << ColorShift.Component) | ColorBytePerPixel.Bpp4,
|
||||
|
@ -38,5 +39,6 @@
|
|||
Y12X12 = (0x24 << ColorShift.Component) | ColorBytePerPixel.Bpp32,
|
||||
X20Y20Z20 = (0x26 << ColorShift.Component) | ColorBytePerPixel.Bpp64,
|
||||
X16Y16Z16W16 = (0x27 << ColorShift.Component) | ColorBytePerPixel.Bpp64,
|
||||
#pragma warning restore IDE0055
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
enum ColorDataType
|
||||
{
|
||||
Integer = 0x0 << ColorShift.DataType,
|
||||
Float = 0x1 << ColorShift.DataType,
|
||||
Stencil = 0x2 << ColorShift.DataType
|
||||
Float = 0x1 << ColorShift.DataType,
|
||||
Stencil = 0x2 << ColorShift.DataType,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
||||
{
|
||||
[SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
|
||||
enum ColorFormat : ulong
|
||||
{
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
NonColor8 = ColorSpace.NonColor | ColorSwizzle.X000 | ColorComponent.X8 | ColorDataType.Integer,
|
||||
NonColor16 = ColorSpace.NonColor | ColorSwizzle.X000 | ColorComponent.X16 | ColorDataType.Integer,
|
||||
NonColor24 = ColorSpace.NonColor | ColorSwizzle.X000 | ColorComponent.X24 | ColorDataType.Integer,
|
||||
|
@ -231,5 +235,6 @@
|
|||
X4Bayer12GBRG = ColorSpace.BayerGBRG | ColorSwizzle.Y000 | ColorComponent.Y4X12 | ColorDataType.Integer,
|
||||
X6Bayer10GBRG = ColorSpace.BayerGBRG | ColorSwizzle.Y000 | ColorComponent.Y6X10 | ColorDataType.Integer,
|
||||
XYZ = ColorSpace.XYZ | ColorSwizzle.XYZ1 | ColorComponent.X20Y20Z20 | ColorDataType.Float,
|
||||
#pragma warning restore IDE0055
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
{
|
||||
class ColorShift
|
||||
{
|
||||
public const int Swizzle = 16;
|
||||
public const int DataType = 14;
|
||||
public const int Space = 32;
|
||||
public const int Swizzle = 16;
|
||||
public const int DataType = 14;
|
||||
public const int Space = 32;
|
||||
public const int Component = 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,32 +2,32 @@
|
|||
{
|
||||
enum ColorSpace : ulong
|
||||
{
|
||||
NonColor = 0x0L << ColorShift.Space,
|
||||
LinearRGBA = 0x1L << ColorShift.Space,
|
||||
SRGB = 0x2L << ColorShift.Space,
|
||||
NonColor = 0x0L << ColorShift.Space,
|
||||
LinearRGBA = 0x1L << ColorShift.Space,
|
||||
SRGB = 0x2L << ColorShift.Space,
|
||||
|
||||
RGB709 = 0x3L << ColorShift.Space,
|
||||
LinearRGB709 = 0x4L << ColorShift.Space,
|
||||
RGB709 = 0x3L << ColorShift.Space,
|
||||
LinearRGB709 = 0x4L << ColorShift.Space,
|
||||
|
||||
LinearScRGB = 0x5L << ColorShift.Space,
|
||||
LinearScRGB = 0x5L << ColorShift.Space,
|
||||
|
||||
RGB2020 = 0x6L << ColorShift.Space,
|
||||
RGB2020 = 0x6L << ColorShift.Space,
|
||||
LinearRGB2020 = 0x7L << ColorShift.Space,
|
||||
RGB2020_PQ = 0x8L << ColorShift.Space,
|
||||
RGB2020_PQ = 0x8L << ColorShift.Space,
|
||||
|
||||
ColorIndex = 0x9L << ColorShift.Space,
|
||||
ColorIndex = 0x9L << ColorShift.Space,
|
||||
|
||||
YCbCr601 = 0xAL << ColorShift.Space,
|
||||
YCbCr601_RR = 0xBL << ColorShift.Space,
|
||||
YCbCr601_ER = 0xCL << ColorShift.Space,
|
||||
YCbCr709 = 0xDL << ColorShift.Space,
|
||||
YCbCr709_ER = 0xEL << ColorShift.Space,
|
||||
YCbCr601 = 0xAL << ColorShift.Space,
|
||||
YCbCr601_RR = 0xBL << ColorShift.Space,
|
||||
YCbCr601_ER = 0xCL << ColorShift.Space,
|
||||
YCbCr709 = 0xDL << ColorShift.Space,
|
||||
YCbCr709_ER = 0xEL << ColorShift.Space,
|
||||
|
||||
BayerRGGB = 0x10L << ColorShift.Space,
|
||||
BayerBGGR = 0x11L << ColorShift.Space,
|
||||
BayerGRBG = 0x12L << ColorShift.Space,
|
||||
BayerGBRG = 0x13L << ColorShift.Space,
|
||||
BayerRGGB = 0x10L << ColorShift.Space,
|
||||
BayerBGGR = 0x11L << ColorShift.Space,
|
||||
BayerGRBG = 0x12L << ColorShift.Space,
|
||||
BayerGBRG = 0x13L << ColorShift.Space,
|
||||
|
||||
XYZ = 0x14L << ColorShift.Space,
|
||||
XYZ = 0x14L << ColorShift.Space,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
{
|
||||
enum ColorSwizzle
|
||||
{
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
XYZW = 0x688 << ColorShift.Swizzle,
|
||||
ZYXW = 0x60a << ColorShift.Swizzle,
|
||||
WZYX = 0x053 << ColorShift.Swizzle,
|
||||
|
@ -26,6 +27,7 @@
|
|||
_000X = 0x124 << ColorShift.Swizzle,
|
||||
_0XY0 = 0x844 << ColorShift.Swizzle,
|
||||
XXXY = 0x200 << ColorShift.Swizzle,
|
||||
YYYX = 0x049 << ColorShift.Swizzle
|
||||
YYYX = 0x049 << ColorShift.Swizzle,
|
||||
#pragma warning restore IDE0055
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,14 +9,14 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
struct GraphicBuffer : IFlattenable
|
||||
{
|
||||
public GraphicBufferHeader Header;
|
||||
public NvGraphicBuffer Buffer;
|
||||
public NvGraphicBuffer Buffer;
|
||||
|
||||
public int Width => Header.Width;
|
||||
public int Height => Header.Height;
|
||||
public PixelFormat Format => Header.Format;
|
||||
public int Usage => Header.Usage;
|
||||
public readonly int Width => Header.Width;
|
||||
public readonly int Height => Header.Height;
|
||||
public readonly PixelFormat Format => Header.Format;
|
||||
public readonly int Usage => Header.Usage;
|
||||
|
||||
public Rect ToRect()
|
||||
public readonly Rect ToRect()
|
||||
{
|
||||
return new Rect(Width, Height);
|
||||
}
|
||||
|
@ -41,34 +41,34 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
Buffer = parcel.ReadUnmanagedType<NvGraphicBuffer>();
|
||||
}
|
||||
|
||||
public void IncrementNvMapHandleRefCount(ulong pid)
|
||||
public readonly void IncrementNvMapHandleRefCount(ulong pid)
|
||||
{
|
||||
NvMapDeviceFile.IncrementMapRefCount(pid, Buffer.NvMapId);
|
||||
|
||||
for (int i = 0; i < Buffer.Surfaces.Length; i++)
|
||||
for (int i = 0; i < NvGraphicBufferSurfaceArray.Length; i++)
|
||||
{
|
||||
NvMapDeviceFile.IncrementMapRefCount(pid, Buffer.Surfaces[i].NvMapHandle);
|
||||
}
|
||||
}
|
||||
|
||||
public void DecrementNvMapHandleRefCount(ulong pid)
|
||||
public readonly void DecrementNvMapHandleRefCount(ulong pid)
|
||||
{
|
||||
NvMapDeviceFile.DecrementMapRefCount(pid, Buffer.NvMapId);
|
||||
|
||||
for (int i = 0; i < Buffer.Surfaces.Length; i++)
|
||||
for (int i = 0; i < NvGraphicBufferSurfaceArray.Length; i++)
|
||||
{
|
||||
NvMapDeviceFile.DecrementMapRefCount(pid, Buffer.Surfaces[i].NvMapHandle);
|
||||
}
|
||||
}
|
||||
|
||||
public uint GetFlattenedSize()
|
||||
public readonly uint GetFlattenedSize()
|
||||
{
|
||||
return (uint)Unsafe.SizeOf<GraphicBuffer>();
|
||||
}
|
||||
|
||||
public uint GetFdCount()
|
||||
public readonly uint GetFdCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,12 +5,12 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
[StructLayout(LayoutKind.Sequential, Size = 0x28, Pack = 1)]
|
||||
struct GraphicBufferHeader
|
||||
{
|
||||
public int Magic;
|
||||
public int Width;
|
||||
public int Height;
|
||||
public int Stride;
|
||||
public int Magic;
|
||||
public int Width;
|
||||
public int Height;
|
||||
public int Stride;
|
||||
public PixelFormat Format;
|
||||
public int Usage;
|
||||
public int Usage;
|
||||
|
||||
public int Pid;
|
||||
public int RefCount;
|
||||
|
@ -18,4 +18,4 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
public int FdsCount;
|
||||
public int IntsCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,4 +38,4 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
[FieldOffset(0x34)]
|
||||
public NvGraphicBufferSurfaceArray Surfaces;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,4 +41,4 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
[FieldOffset(0x38)]
|
||||
public long Size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,27 +15,20 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
[FieldOffset(0xb0)]
|
||||
private NvGraphicBufferSurface Surface2;
|
||||
|
||||
public NvGraphicBufferSurface this[int index]
|
||||
public readonly NvGraphicBufferSurface this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (index == 0)
|
||||
return index switch
|
||||
{
|
||||
return Surface0;
|
||||
}
|
||||
else if (index == 1)
|
||||
{
|
||||
return Surface1;
|
||||
}
|
||||
else if (index == 2)
|
||||
{
|
||||
return Surface2;
|
||||
}
|
||||
|
||||
throw new IndexOutOfRangeException();
|
||||
0 => Surface0,
|
||||
1 => Surface1,
|
||||
2 => Surface2,
|
||||
_ => throw new IndexOutOfRangeException(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public int Length => 3;
|
||||
public static int Length => 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,18 +11,18 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
public int Right;
|
||||
public int Bottom;
|
||||
|
||||
public int Width => Right - Left;
|
||||
public int Height => Bottom - Top;
|
||||
public readonly int Width => Right - Left;
|
||||
public readonly int Height => Bottom - Top;
|
||||
|
||||
public Rect(int width, int height)
|
||||
{
|
||||
Left = 0;
|
||||
Top = 0;
|
||||
Right = width;
|
||||
Left = 0;
|
||||
Top = 0;
|
||||
Right = width;
|
||||
Bottom = height;
|
||||
}
|
||||
|
||||
public bool IsEmpty()
|
||||
public readonly bool IsEmpty()
|
||||
{
|
||||
return Width <= 0 || Height <= 0;
|
||||
}
|
||||
|
@ -31,10 +31,10 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
{
|
||||
result = new Rect
|
||||
{
|
||||
Left = Math.Max(Left, other.Left),
|
||||
Top = Math.Max(Top, other.Top),
|
||||
Right = Math.Min(Right, other.Right),
|
||||
Bottom = Math.Min(Bottom, other.Bottom)
|
||||
Left = Math.Max(Left, other.Left),
|
||||
Top = Math.Max(Top, other.Top),
|
||||
Right = Math.Min(Right, other.Right),
|
||||
Bottom = Math.Min(Bottom, other.Bottom),
|
||||
};
|
||||
|
||||
return !result.IsEmpty();
|
||||
|
@ -42,7 +42,7 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
|
||||
public void MakeInvalid()
|
||||
{
|
||||
Right = -1;
|
||||
Right = -1;
|
||||
Bottom = -1;
|
||||
}
|
||||
|
||||
|
@ -56,16 +56,16 @@ namespace Ryujinx.HLE.HOS.Services.SurfaceFlinger
|
|||
return !x.Equals(y);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
public readonly override bool Equals(object obj)
|
||||
{
|
||||
return obj is Rect rect && Equals(rect);
|
||||
}
|
||||
|
||||
public bool Equals(Rect cmpObj)
|
||||
public readonly bool Equals(Rect cmpObj)
|
||||
{
|
||||
return Left == cmpObj.Left && Top == cmpObj.Top && Right == cmpObj.Right && Bottom == cmpObj.Bottom;
|
||||
}
|
||||
|
||||
public override int GetHashCode() => HashCode.Combine(Left, Top, Right, Bottom);
|
||||
public readonly override int GetHashCode() => HashCode.Combine(Left, Top, Right, Bottom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue