Force cache to remove entries when memory usage exceeds a given threshold (#492)

This commit is contained in:
gdkchan 2018-11-14 20:22:02 -02:00 committed by Ac_K
parent 453543fb88
commit 85ffd76016
4 changed files with 30 additions and 7 deletions

View file

@ -8,7 +8,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{ {
public delegate void DeleteValue(T Value); public delegate void DeleteValue(T Value);
private const int MaxTimeDelta = 5 * 60000; private const int MinTimeDelta = 5 * 60000;
private const int MaxRemovalsPerRun = 10; private const int MaxRemovalsPerRun = 10;
private struct CacheBucket private struct CacheBucket
@ -41,8 +41,13 @@ namespace Ryujinx.Graphics.Gal.OpenGL
private bool Locked; private bool Locked;
public OGLCachedResource(DeleteValue DeleteValueCallback) private long MaxSize;
private long TotalSize;
public OGLCachedResource(DeleteValue DeleteValueCallback, long MaxSize)
{ {
this.MaxSize = MaxSize;
if (DeleteValueCallback == null) if (DeleteValueCallback == null)
{ {
throw new ArgumentNullException(nameof(DeleteValueCallback)); throw new ArgumentNullException(nameof(DeleteValueCallback));
@ -98,12 +103,16 @@ namespace Ryujinx.Graphics.Gal.OpenGL
SortedCache.Remove(Bucket.Node); SortedCache.Remove(Bucket.Node);
TotalSize -= Bucket.DataSize;
Cache[Key] = NewBucket; Cache[Key] = NewBucket;
} }
else else
{ {
Cache.Add(Key, NewBucket); Cache.Add(Key, NewBucket);
} }
TotalSize += Size;
} }
public bool TryGetValue(long Key, out T Value) public bool TryGetValue(long Key, out T Value)
@ -159,7 +168,7 @@ namespace Ryujinx.Graphics.Gal.OpenGL
long TimeDelta = Timestamp - Bucket.Timestamp; long TimeDelta = Timestamp - Bucket.Timestamp;
if ((uint)TimeDelta <= (uint)MaxTimeDelta) if (TimeDelta <= MinTimeDelta && !UnderMemoryPressure())
{ {
break; break;
} }
@ -169,7 +178,14 @@ namespace Ryujinx.Graphics.Gal.OpenGL
Cache.Remove(Node.Value); Cache.Remove(Node.Value);
DeleteValueCallback(Bucket.Value); DeleteValueCallback(Bucket.Value);
}
TotalSize -= Bucket.DataSize;
}
}
private bool UnderMemoryPressure()
{
return TotalSize >= MaxSize;
} }
} }
} }

View file

@ -5,11 +5,13 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{ {
class OGLConstBuffer : IGalConstBuffer class OGLConstBuffer : IGalConstBuffer
{ {
private const long MaxConstBufferCacheSize = 64 * 1024 * 1024;
private OGLCachedResource<OGLStreamBuffer> Cache; private OGLCachedResource<OGLStreamBuffer> Cache;
public OGLConstBuffer() public OGLConstBuffer()
{ {
Cache = new OGLCachedResource<OGLStreamBuffer>(DeleteBuffer); Cache = new OGLCachedResource<OGLStreamBuffer>(DeleteBuffer, MaxConstBufferCacheSize);
} }
public void LockCache() public void LockCache()

View file

@ -5,6 +5,9 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{ {
class OGLRasterizer : IGalRasterizer class OGLRasterizer : IGalRasterizer
{ {
private const long MaxVertexBufferCacheSize = 128 * 1024 * 1024;
private const long MaxIndexBufferCacheSize = 64 * 1024 * 1024;
private int[] VertexBuffers; private int[] VertexBuffers;
private OGLCachedResource<int> VboCache; private OGLCachedResource<int> VboCache;
@ -24,8 +27,8 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{ {
VertexBuffers = new int[32]; VertexBuffers = new int[32];
VboCache = new OGLCachedResource<int>(GL.DeleteBuffer); VboCache = new OGLCachedResource<int>(GL.DeleteBuffer, MaxVertexBufferCacheSize);
IboCache = new OGLCachedResource<int>(GL.DeleteBuffer); IboCache = new OGLCachedResource<int>(GL.DeleteBuffer, MaxIndexBufferCacheSize);
IndexBuffer = new IbInfo(); IndexBuffer = new IbInfo();
} }

View file

@ -6,13 +6,15 @@ namespace Ryujinx.Graphics.Gal.OpenGL
{ {
class OGLTexture : IGalTexture class OGLTexture : IGalTexture
{ {
private const long MaxTextureCacheSize = 768 * 1024 * 1024;
private OGLCachedResource<ImageHandler> TextureCache; private OGLCachedResource<ImageHandler> TextureCache;
public EventHandler<int> TextureDeleted { get; set; } public EventHandler<int> TextureDeleted { get; set; }
public OGLTexture() public OGLTexture()
{ {
TextureCache = new OGLCachedResource<ImageHandler>(DeleteTexture); TextureCache = new OGLCachedResource<ImageHandler>(DeleteTexture, MaxTextureCacheSize);
} }
public void LockCache() public void LockCache()