diff --git a/class/System.Windows/Mono/GeneratedPInvokes.cs b/class/System.Windows/Mono/GeneratedPInvokes.cs index b2dd506..f00ec48 100644 --- a/class/System.Windows/Mono/GeneratedPInvokes.cs +++ b/class/System.Windows/Mono/GeneratedPInvokes.cs @@ -260,8 +260,8 @@ namespace Mono { public extern static void bitmap_source_invalidate (IntPtr instance); [DllImport ("moon")] - // void bitmap_source_set_bitmap_data (BitmapSource *instance, gpointer data); - public extern static void bitmap_source_set_bitmap_data (IntPtr instance, IntPtr data); + // void bitmap_source_set_bitmap_data (BitmapSource *instance, gpointer data, bool own); + public extern static void bitmap_source_set_bitmap_data (IntPtr instance, IntPtr data, [MarshalAs (UnmanagedType.U1)] bool own); [DllImport ("moon")] // Border *border_new (); diff --git a/class/System.Windows/System.Windows.Media.Imaging/BitmapSource.cs b/class/System.Windows/System.Windows.Media.Imaging/BitmapSource.cs index 98f0778..37072ba 100644 --- a/class/System.Windows/System.Windows.Media.Imaging/BitmapSource.cs +++ b/class/System.Windows/System.Windows.Media.Imaging/BitmapSource.cs @@ -38,7 +38,7 @@ namespace System.Windows.Media.Imaging public void SetSource (Stream streamSource) { if (streamSource == null) - NativeMethods.bitmap_source_set_bitmap_data (native, IntPtr.Zero); + NativeMethods.bitmap_source_set_bitmap_data (native, IntPtr.Zero, true); else { NativeMethods.bitmap_image_pixbuf_write (native, Helper.StreamToIntPtr (streamSource), 0, (int) streamSource.Length); NativeMethods.bitmap_image_pixmap_complete (native); diff --git a/class/System.Windows/System.Windows.Media.Imaging/ChangeLog b/class/System.Windows/System.Windows.Media.Imaging/ChangeLog index 0093a03..8bd7d06 100644 --- a/class/System.Windows/System.Windows.Media.Imaging/ChangeLog +++ b/class/System.Windows/System.Windows.Media.Imaging/ChangeLog @@ -1,5 +1,15 @@ 2009-08-12 Chris Toshok + * WriteableBitmap.cs: we need to pin the pixel data in both ctors, + so factor that out into PinAndSetBitmapData. Also, pass false to + bitmap_source_set_bitmap_data, so unmanaged won't free our buffer. + it's freed in our finalizer. fixes the double free on shutdown. + + * BitmapSource.cs (SetSource): pass true for @own to + bitmap_source_set_bitmap_data. + +2009-08-12 Chris Toshok + * WriteableBitmap.cs: track changes to the api from SL3 beta to RTM. diff --git a/class/System.Windows/System.Windows.Media.Imaging/WriteableBitmap.cs b/class/System.Windows/System.Windows.Media.Imaging/WriteableBitmap.cs index 6e591e4..27ef16e 100644 --- a/class/System.Windows/System.Windows.Media.Imaging/WriteableBitmap.cs +++ b/class/System.Windows/System.Windows.Media.Imaging/WriteableBitmap.cs @@ -63,6 +63,8 @@ namespace System.Windows.Media.Imaging IntPtr bitmap_data = NativeMethods.bitmap_source_get_bitmap_data (source.native); if (bitmap_data != IntPtr.Zero) Marshal.Copy (bitmap_data, pixels, 0, pixels.Length); + + PinAndSetBitmapData (); } public WriteableBitmap (int width, int height) : base (NativeMethods.writeable_bitmap_new (), true) @@ -73,9 +75,14 @@ namespace System.Windows.Media.Imaging pixels = new int[PixelWidth * PixelHeight]; + PinAndSetBitmapData (); + } + + void PinAndSetBitmapData () + { pixels_handle = GCHandle.Alloc(pixels, GCHandleType.Pinned); // pin it so it doesn't move - NativeMethods.bitmap_source_set_bitmap_data (native, pixels_handle.AddrOfPinnedObject()); + NativeMethods.bitmap_source_set_bitmap_data (native, pixels_handle.AddrOfPinnedObject(), false); } ~WriteableBitmap () diff --git a/class/tuning/SecurityAttributes/automatic/System.Windows.auto.sc b/class/tuning/SecurityAttributes/automatic/System.Windows.auto.sc index 2937d35..82ced5e 100644 --- a/class/tuning/SecurityAttributes/automatic/System.Windows.auto.sc +++ b/class/tuning/SecurityAttributes/automatic/System.Windows.auto.sc @@ -1,5 +1,5 @@ # [SecurityCritical] needed to execute code inside 'System.Windows, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e'. -# 539 methods needs to be decorated. +# 540 methods needs to be decorated. # p/invoke declaration +SC-M: Mono.Kind Mono.NativeMethods::collection_get_element_type(System.IntPtr) @@ -401,6 +401,9 @@ +SC-M: System.IntPtr Mono.NativeMethods::bitmap_image_new() # p/invoke declaration ++SC-M: System.IntPtr Mono.NativeMethods::bitmap_source_get_bitmap_data(System.IntPtr) + +# p/invoke declaration +SC-M: System.IntPtr Mono.NativeMethods::bitmap_source_new() # p/invoke declaration @@ -1196,7 +1199,7 @@ +SC-M: System.Void Mono.NativeMethods::bitmap_source_invalidate(System.IntPtr) # p/invoke declaration -+SC-M: System.Void Mono.NativeMethods::bitmap_source_set_bitmap_data(System.IntPtr,System.IntPtr) ++SC-M: System.Void Mono.NativeMethods::bitmap_source_set_bitmap_data(System.IntPtr,System.IntPtr,System.Boolean) # p/invoke declaration +SC-M: System.Void Mono.NativeMethods::collection_changed_event_args_set_index(System.IntPtr,System.Int32) diff --git a/class/tuning/SecurityAttributes/automatic/System.Windows.auto.ssc b/class/tuning/SecurityAttributes/automatic/System.Windows.auto.ssc index 1eb4777..a16cf66 100644 --- a/class/tuning/SecurityAttributes/automatic/System.Windows.auto.ssc +++ b/class/tuning/SecurityAttributes/automatic/System.Windows.auto.ssc @@ -1,5 +1,5 @@ # [SecuritySafeCritical] needed inside System.Windows to call all [SecurityCritical] methods -# 469 methods +# 470 methods +SSC-M: System.Void Microsoft.Internal.TextBoxView::.ctor() +SSC-M: Mono.Xaml.ManagedXamlLoader Mono.ApplicationLauncher::CreateXamlLoader(System.IntPtr,System.IntPtr,System.IntPtr,System.String,System.String,System.String) @@ -329,6 +329,7 @@ +SSC-M: System.Void System.Windows.Media.Imaging.WriteableBitmap::.ctor() +SSC-M: System.Void System.Windows.Media.Imaging.WriteableBitmap::.ctor(System.Windows.Media.Imaging.BitmapSource) +SSC-M: System.Void System.Windows.Media.Imaging.WriteableBitmap::.ctor(System.Int32,System.Int32) ++SSC-M: System.Void System.Windows.Media.Imaging.WriteableBitmap::PinAndSetBitmapData() +SSC-M: System.Void System.Windows.Media.Imaging.WriteableBitmap::Finalize() +SSC-M: System.Void System.Windows.Media.Imaging.WriteableBitmap::Render(System.Windows.UIElement,System.Windows.Media.Transform) +SSC-M: System.Void System.Windows.Media.Imaging.WriteableBitmap::Invalidate() diff --git a/src/ChangeLog b/src/ChangeLog index 0c9d5c0..c5f91f2 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,11 @@ +2009-08-12 Chris Toshok + + * bitmapsource.h|cpp (SetBitmapData): add an extra parameter + "own" (default: true) which, if true, causes the bitmap source to + free the bitmapdata when it's destroyed. + + * cbinding.h|cpp: regen + 2009-08-12 Stephane Delcroix * multiscaleimage.cpp: clear the cache on source change, cache a NULL diff --git a/src/bitmapsource.cpp b/src/bitmapsource.cpp index 57954a1..893ddbb 100644 --- a/src/bitmapsource.cpp +++ b/src/bitmapsource.cpp @@ -25,6 +25,7 @@ BitmapSource::BitmapSource () image_surface = NULL; native_surface = NULL; data = NULL; + own_data = true; } BitmapSource::~BitmapSource () @@ -34,8 +35,8 @@ BitmapSource::~BitmapSource () if (native_surface) cairo_surface_destroy (native_surface); - if (this->data) - g_free (this->data); + if (data && own_data) + g_free (data); } gpointer @@ -45,10 +46,11 @@ BitmapSource::GetBitmapData () } void -BitmapSource::SetBitmapData (gpointer data) +BitmapSource::SetBitmapData (gpointer data, bool own_data) { - if (this->data) + if (this->data && this->own_data) g_free (this->data); + this->own_data = own_data; this->data = data; } diff --git a/src/bitmapsource.h b/src/bitmapsource.h index 8f161db..7c97fee 100644 --- a/src/bitmapsource.h +++ b/src/bitmapsource.h @@ -22,7 +22,7 @@ class BitmapSource : public ImageSource { private: cairo_surface_t *native_surface; gpointer data; - + bool own_data; // if true, we free in the dtor. protected: cairo_surface_t *image_surface; @@ -49,7 +49,7 @@ class BitmapSource : public ImageSource { /* @GenerateCBinding,GeneratePInvoke */ gpointer GetBitmapData (); /* @GenerateCBinding,GeneratePInvoke */ - void SetBitmapData (gpointer data); + void SetBitmapData (gpointer data, bool own = true); PixelFormats GetPixelFormat (); void SetPixelFormat (PixelFormats weight); diff --git a/src/cbinding.cpp b/src/cbinding.cpp index f53dc8b..7656cb2 100644 --- a/src/cbinding.cpp +++ b/src/cbinding.cpp @@ -557,12 +557,12 @@ bitmap_source_invalidate (BitmapSource *instance) void -bitmap_source_set_bitmap_data (BitmapSource *instance, gpointer data) +bitmap_source_set_bitmap_data (BitmapSource *instance, gpointer data, bool own) { if (instance == NULL) return; - instance->SetBitmapData (data); + instance->SetBitmapData (data, own); } diff --git a/src/cbinding.h b/src/cbinding.h index c645984..648ae79 100644 --- a/src/cbinding.h +++ b/src/cbinding.h @@ -947,7 +947,7 @@ gpointer bitmap_source_get_bitmap_data (BitmapSource *instance); void bitmap_source_invalidate (BitmapSource *instance); /* @GeneratePInvoke */ -void bitmap_source_set_bitmap_data (BitmapSource *instance, gpointer data); +void bitmap_source_set_bitmap_data (BitmapSource *instance, gpointer data, bool own); /** * Border