Reduce working set by releasing buffers for sheets.

Sheets carry a managed buffer of data that allows updates to be made without having to constantly fetch and set data to the texture memory of the video card. This is useful for things like SheetBuilder which make small progressive changes to sheets.

However these buffers are often large and are kept alive because sheets are referenced by the sprites that use them. If this buffer is explicitly null'ed when it is no longer needed then the GC can reclaim it. Sometimes a buffer need not even be created because the object using the sheet only works on the texture directly anyway.

In practise, this reduced memory consumed by such buffers from ~165 MiB to ~112 MiB (at the start of a new RA skirmish mission).
This commit is contained in:
RoosterDragon
2014-06-22 16:01:55 +01:00
parent 0d61a1d19a
commit 3a30748f05
11 changed files with 97 additions and 57 deletions

View File

@@ -51,8 +51,9 @@ namespace OpenRA.Mods.RA.Widgets
back = new byte[4*256*256];
var rect = new Rectangle((int)(255*SRange[0]), (int)(255*(1 - VRange[1])), (int)(255*(SRange[1] - SRange[0]))+1, (int)(255*(VRange[1] - VRange[0])) + 1);
mixerSprite = new Sprite(new Sheet(new Size(256, 256)), rect, TextureChannel.Alpha);
mixerSprite.sheet.Texture.SetData(front, 256, 256);
var mixerSheet = new Sheet(new Size(256, 256), false);
mixerSheet.Texture.SetData(front, 256, 256);
mixerSprite = new Sprite(mixerSheet, rect, TextureChannel.Alpha);
}
void GenerateBitmap()

View File

@@ -1,6 +1,6 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
* Copyright 2007-2014 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation. For more information,
@@ -19,8 +19,8 @@ namespace OpenRA.Mods.RA.Widgets
{
Sprite hueSprite;
public HueSliderWidget() {}
public HueSliderWidget(HueSliderWidget other) : base(other) {}
public HueSliderWidget() { }
public HueSliderWidget(HueSliderWidget other) : base(other) { }
public override void Initialize(WidgetArgs args)
{
@@ -28,7 +28,8 @@ namespace OpenRA.Mods.RA.Widgets
using (var hueBitmap = new Bitmap(256, 256))
{
hueSprite = new Sprite(new Sheet(new Size(256, 256)), new Rectangle(0, 0, 256, 1), TextureChannel.Alpha);
var hueSheet = new Sheet(new Size(256, 256), false);
hueSprite = new Sprite(hueSheet, new Rectangle(0, 0, 256, 1), TextureChannel.Alpha);
var bitmapData = hueBitmap.LockBits(hueBitmap.Bounds(),
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
@@ -39,8 +40,7 @@ namespace OpenRA.Mods.RA.Widgets
*(c + h) = HSLColor.FromHSV(h / 255f, 1, 1).RGB.ToArgb();
}
hueBitmap.UnlockBits(bitmapData);
hueSprite.sheet.Texture.SetData(hueBitmap);
hueSheet.Texture.SetData(hueBitmap);
}
}
@@ -54,9 +54,8 @@ namespace OpenRA.Mods.RA.Widgets
Game.Renderer.RgbaSpriteRenderer.DrawSprite(hueSprite, ro, new float2(rb.Size));
var sprite = ChromeProvider.GetImage("lobby-bits", "huepicker");
var pos = RenderOrigin + new int2(PxFromValue(Value).Clamp(0, rb.Width-1) - sprite.bounds.Width/2, (rb.Height-sprite.bounds.Height)/2);
var pos = RenderOrigin + new int2(PxFromValue(Value).Clamp(0, rb.Width - 1) - sprite.bounds.Width / 2, (rb.Height - sprite.bounds.Height) / 2);
Game.Renderer.RgbaSpriteRenderer.DrawSprite(sprite, pos);
}
}
}

View File

@@ -72,13 +72,14 @@ namespace OpenRA.Mods.RA.Widgets
{
var r = new Rectangle(0, 0, width, height);
var s = new Size(terrainBitmap.Width, terrainBitmap.Height);
terrainSprite = new Sprite(new Sheet(s), r, TextureChannel.Alpha);
terrainSprite.sheet.Texture.SetData(terrainBitmap);
var terrainSheet = new Sheet(s, false);
terrainSheet.Texture.SetData(terrainBitmap);
terrainSprite = new Sprite(terrainSheet, r, TextureChannel.Alpha);
// Data is set in Tick()
customTerrainSprite = new Sprite(new Sheet(s), r, TextureChannel.Alpha);
actorSprite = new Sprite(new Sheet(s), r, TextureChannel.Alpha);
shroudSprite = new Sprite(new Sheet(s), r, TextureChannel.Alpha);
customTerrainSprite = new Sprite(new Sheet(s, false), r, TextureChannel.Alpha);
actorSprite = new Sprite(new Sheet(s, false), r, TextureChannel.Alpha);
shroudSprite = new Sprite(new Sheet(s, false), r, TextureChannel.Alpha);
}
}