diff options
author | Alex Corrado <alexc@xamarin.com> | 2014-01-29 04:39:29 +0400 |
---|---|---|
committer | Alex Corrado <alexc@xamarin.com> | 2014-01-29 04:39:29 +0400 |
commit | 326fb7ab44808634da4307530f112c9acb62b972 (patch) | |
tree | bfef91cbb094e0c8fa4595e6f69b26e54efd87e3 | |
parent | bf862f0f9b6a965793164fb9ebe665131ed3f8f5 (diff) |
Ref count vector image data objectscorrado/ref-count-vector-data
-rw-r--r-- | Xwt.Gtk/Xwt.GtkBackend/ImagePatternBackendHandler.cs | 6 | ||||
-rw-r--r-- | Xwt/Xwt.Backends/ResourceManager.cs | 31 | ||||
-rw-r--r-- | Xwt/Xwt.Drawing/Image.cs | 4 | ||||
-rw-r--r-- | Xwt/Xwt.Drawing/ImageBuilder.cs | 15 | ||||
-rw-r--r-- | Xwt/Xwt.Drawing/VectorImage.cs | 31 |
5 files changed, 68 insertions, 19 deletions
diff --git a/Xwt.Gtk/Xwt.GtkBackend/ImagePatternBackendHandler.cs b/Xwt.Gtk/Xwt.GtkBackend/ImagePatternBackendHandler.cs index e77b857b..40f03849 100644 --- a/Xwt.Gtk/Xwt.GtkBackend/ImagePatternBackendHandler.cs +++ b/Xwt.Gtk/Xwt.GtkBackend/ImagePatternBackendHandler.cs @@ -51,7 +51,7 @@ namespace Xwt.GtkBackend #endregion } - class ImagePatternBackend + class ImagePatternBackend : IDisposable { public ImageDescription Image; @@ -84,8 +84,10 @@ namespace Xwt.GtkBackend public void Dispose () { - if (pattern != null) + if (pattern != null) { pattern.Dispose (); + pattern = null; + } } } } diff --git a/Xwt/Xwt.Backends/ResourceManager.cs b/Xwt/Xwt.Backends/ResourceManager.cs index f954b374..b3b90818 100644 --- a/Xwt/Xwt.Backends/ResourceManager.cs +++ b/Xwt/Xwt.Backends/ResourceManager.cs @@ -30,16 +30,33 @@ namespace Xwt.Backends { static class ResourceManager { + class Ref { + public int RefCount; + public Action<object> Disposer; + + public Ref (Action<object> disposer) + { + RefCount = 1; + Disposer = disposer; + } + } + static bool finalized; - static Dictionary<object,Action<object>> resources = new Dictionary<object,Action<object>> (); + static Dictionary<object,Ref> resources = new Dictionary<object,Ref> (); static Dictionary<object,Action<object>> freedResources = new Dictionary<object,Action<object>> (); public static void RegisterResource (object res, Action<object> disposeCallback = null) { if (finalized) return; - lock (resources) - resources [res] = disposeCallback; + + Ref reference; + lock (resources) { + if (resources.TryGetValue (res, out reference)) + reference.RefCount++; + else + resources.Add (res, new Ref (disposeCallback)); + } } public static bool FreeResource (object res) @@ -48,19 +65,19 @@ namespace Xwt.Backends return true; lock (resources) { - Action<object> disposer; - if (!resources.TryGetValue (res, out disposer)) + Ref reference; + if (!resources.TryGetValue (res, out reference) || --reference.RefCount > 0) return false; resources.Remove (res); if (System.Threading.Thread.CurrentThread == Application.UIThread) { - DisposeResource (res, disposer); + DisposeResource (res, reference.Disposer); } else { lock (freedResources) { if (freedResources.Count == 0) Application.Invoke (DisposeResources); - freedResources [res] = disposer; + freedResources [res] = reference.Disposer; } } return true; diff --git a/Xwt/Xwt.Drawing/Image.cs b/Xwt/Xwt.Drawing/Image.cs index 240aa497..81513515 100644 --- a/Xwt/Xwt.Drawing/Image.cs +++ b/Xwt/Xwt.Drawing/Image.cs @@ -87,8 +87,10 @@ namespace Xwt.Drawing protected virtual void Dispose (bool disposing) { - if (NativeRef != null) + if (NativeRef != null) { NativeRef.ReleaseReference (disposing); + NativeRef = null; + } } diff --git a/Xwt/Xwt.Drawing/ImageBuilder.cs b/Xwt/Xwt.Drawing/ImageBuilder.cs index 172677fe..0728bb9d 100644 --- a/Xwt/Xwt.Drawing/ImageBuilder.cs +++ b/Xwt/Xwt.Drawing/ImageBuilder.cs @@ -73,27 +73,32 @@ namespace Xwt.Drawing public BitmapImage ToBitmap (ImageFormat format = ImageFormat.ARGB32) { - return ToVectorImage ().ToBitmap (format); + using (var vector = ToVectorImage ()) + return vector.ToBitmap (format); } public BitmapImage ToBitmap (Widget renderTarget, ImageFormat format = ImageFormat.ARGB32) { - return ToVectorImage ().ToBitmap (renderTarget, format); + using (var vector = ToVectorImage ()) + return vector.ToBitmap (renderTarget, format); } public BitmapImage ToBitmap (Window renderTarget, ImageFormat format = ImageFormat.ARGB32) { - return ToVectorImage ().ToBitmap (renderTarget, format); + using (var vector = ToVectorImage ()) + return vector.ToBitmap (renderTarget, format); } public BitmapImage ToBitmap (Screen renderTarget, ImageFormat format = ImageFormat.ARGB32) { - return ToVectorImage ().ToBitmap (renderTarget, format); + using (var vector = ToVectorImage ()) + return vector.ToBitmap (renderTarget, format); } public BitmapImage ToBitmap (double scaleFactor, ImageFormat format = ImageFormat.ARGB32) { - return ToVectorImage ().ToBitmap (scaleFactor, format); + using (var vector = ToVectorImage ()) + return vector.ToBitmap (scaleFactor, format); } } } diff --git a/Xwt/Xwt.Drawing/VectorImage.cs b/Xwt/Xwt.Drawing/VectorImage.cs index 0644ca69..eaa53c44 100644 --- a/Xwt/Xwt.Drawing/VectorImage.cs +++ b/Xwt/Xwt.Drawing/VectorImage.cs @@ -48,9 +48,15 @@ namespace Xwt.Drawing ToolkitEngine.VectorImageRecorderContextHandler.Draw (ctx.Handler, Toolkit.GetBackend (ctx), data); ctx.Restore (); } + + protected override void Dispose (bool disposing) + { + base.Dispose (disposing); + data.Dispose (); + } } - class VectorImageData + class VectorImageData : IDisposable { public DrawingCommand[] Commands; public double[] Doubles; @@ -60,6 +66,12 @@ namespace Xwt.Drawing public object[] Objects; public ImageDescription[] Images; public TextLayoutData[] TextLayouts; + + public void Dispose () + { + foreach (var obj in Objects) + ResourceManager.FreeResource (obj); + } } enum DrawingCommand @@ -204,22 +216,32 @@ namespace Xwt.Drawing public VectorImageData ToVectorImageData () { - return new VectorImageData () { + var data = new VectorImageData () { Commands = Commands.ToArray (), Doubles = Doubles.ToArray (), Colors = Colors.ToArray (), Images = Images.ToArray (), Ints = Ints.ToArray (), Rectangles = Rectangles.ToArray (), - Objects = Objects.ToArray (), TextLayouts = TextLayouts.ToArray (), }; + data.Objects = new object [Objects.Count]; + for (var i = 0; i < Objects.Count; i++) { + var obj = Objects [i]; + data.Objects [i] = obj; + ResourceManager.RegisterResource (obj); + } + return data; } public virtual void Dispose () { - if (NativeBackend != null) + if (NativeBackend != null) { NativePathHandler.Dispose (NativeBackend); + NativeBackend = null; + } + foreach (var obj in Objects) + ResourceManager.FreeResource (obj); } } @@ -486,6 +508,7 @@ namespace Xwt.Drawing var ctx = (VectorBackend)backend; ctx.Commands.Add (DrawingCommand.SetPattern); ctx.Objects.Add (p); + ResourceManager.RegisterResource (p); } public override void DrawTextLayout (object backend, TextLayout layout, double x, double y) |