NvdecDevice.cs
1 using Ryujinx.Common.Logging; 2 using Ryujinx.Graphics.Device; 3 using Ryujinx.Graphics.Nvdec.Image; 4 using System.Collections.Concurrent; 5 using System.Collections.Generic; 6 using System.Threading; 7 8 namespace Ryujinx.Graphics.Nvdec 9 { 10 public class NvdecDevice : IDeviceStateWithContext 11 { 12 private readonly ResourceManager _rm; 13 private readonly DeviceState<NvdecRegisters> _state; 14 15 private long _currentId; 16 private readonly ConcurrentDictionary<long, NvdecDecoderContext> _contexts; 17 private NvdecDecoderContext _currentContext; 18 19 public NvdecDevice(DeviceMemoryManager mm) 20 { 21 _rm = new ResourceManager(mm, new SurfaceCache(mm)); 22 _state = new DeviceState<NvdecRegisters>(new Dictionary<string, RwCallback> 23 { 24 { nameof(NvdecRegisters.Execute), new RwCallback(Execute, null) }, 25 }); 26 _contexts = new ConcurrentDictionary<long, NvdecDecoderContext>(); 27 } 28 29 public long CreateContext() 30 { 31 long id = Interlocked.Increment(ref _currentId); 32 _contexts.TryAdd(id, new NvdecDecoderContext()); 33 34 return id; 35 } 36 37 public void DestroyContext(long id) 38 { 39 if (_contexts.TryRemove(id, out var context)) 40 { 41 context.Dispose(); 42 } 43 44 _rm.Cache.Trim(); 45 } 46 47 public void BindContext(long id) 48 { 49 if (_contexts.TryGetValue(id, out var context)) 50 { 51 _currentContext = context; 52 } 53 } 54 55 public int Read(int offset) => _state.Read(offset); 56 public void Write(int offset, int data) => _state.Write(offset, data); 57 58 private void Execute(int data) 59 { 60 Decode((ApplicationId)_state.State.SetApplicationId); 61 } 62 63 private void Decode(ApplicationId applicationId) 64 { 65 switch (applicationId) 66 { 67 case ApplicationId.H264: 68 H264Decoder.Decode(_currentContext, _rm, ref _state.State); 69 break; 70 case ApplicationId.Vp8: 71 Vp8Decoder.Decode(_currentContext, _rm, ref _state.State); 72 break; 73 case ApplicationId.Vp9: 74 Vp9Decoder.Decode(_rm, ref _state.State); 75 break; 76 default: 77 Logger.Error?.Print(LogClass.Nvdec, $"Unsupported codec \"{applicationId}\"."); 78 break; 79 } 80 } 81 } 82 }