All pastes #294625 Raw Edit

Untitled

public text v1 · immutable
#294625 ·published 2006-12-28 18:10 UTC
rendered paste body
Index: System.Windows.Forms/Control.cs
===================================================================
--- System.Windows.Forms/Control.cs	(revision 70171)
+++ System.Windows.Forms/Control.cs	(working copy)
@@ -127,10 +127,8 @@
 		ContextMenu             context_menu; // Context menu associated with the control
 
 		// double buffering
-		Graphics                backbuffer_dc;
-		object                  backbuffer;
-		Region                  invalid_region;
-
+		DoubleBuffer            backbuffer;
+		
 		// to implement DeviceContext without depending on double buffering
 		Bitmap bmp;
 		Graphics bmp_g;
@@ -298,7 +296,98 @@
 
 			#endregion	// ControlAccessibleObject Public Instance Methods
 		}
+		
+		private class DoubleBuffer : IDisposable
+		{
+			public Region InvalidRegion;
+			private Stack real_graphics;
+			private object back_buffer;
+			private Control parent;
+			private bool pending_disposal;
+			
+			public DoubleBuffer (Control parent)
+			{
+				this.parent = parent;
+				real_graphics = new Stack ();
+				int width = parent.Width;
+				int height = parent.Height;
 
+				if (width < 1) width = 1;
+				if (height < 1) height = 1;
+
+				XplatUI.CreateOffscreenDrawable (parent.Handle, width, height, out back_buffer);
+				Invalidate ();
+			}
+			
+			public void Blit (PaintEventArgs pe)
+			{
+				Graphics buffered_graphics;
+				buffered_graphics = XplatUI.GetOffscreenGraphics (back_buffer);
+				XplatUI.BlitFromOffscreen (parent.Handle, pe.Graphics, back_buffer, buffered_graphics, pe.ClipRectangle);
+				buffered_graphics.Dispose ();
+			}
+			
+			public void Start (PaintEventArgs pe)
+			{				
+				// We need to get the graphics for every paint.
+				real_graphics.Push(pe.SetGraphics (XplatUI.GetOffscreenGraphics (back_buffer)));
+			}
+
+			public void End (PaintEventArgs pe)
+			{
+				Graphics buffered_graphics;
+				buffered_graphics = pe.SetGraphics ((Graphics) real_graphics.Pop ());
+
+				if (pending_disposal) 
+					Dispose ();
+				else {
+					XplatUI.BlitFromOffscreen (parent.Handle, pe.Graphics, back_buffer, buffered_graphics, pe.ClipRectangle);
+					InvalidRegion.Exclude (pe.ClipRectangle);
+				}
+				buffered_graphics.Dispose ();
+			}
+			
+			public void Invalidate ()
+			{
+				if (InvalidRegion != null)
+					InvalidRegion.Dispose ();
+				InvalidRegion = new Region (parent.ClientRectangle);
+			}
+			
+			public void Dispose ()
+			{
+				if (real_graphics.Count > 0) {
+					pending_disposal = true;
+					return;
+				}
+				
+				XplatUI.DestroyOffscreenDrawable (back_buffer);
+
+				if (InvalidRegion != null)
+					InvalidRegion.Dispose ();
+				InvalidRegion = null;
+				back_buffer = null;
+				GC.SuppressFinalize (this);
+			}
+
+			#region IDisposable Members
+			void IDisposable.Dispose ()
+			{
+				Dispose ();
+			}
+			#endregion
+			
+			~DoubleBuffer ()
+			{
+				Dispose ();
+			}
+		}
+	class a 
+	{
+		~a ()
+		{
+		}
+	}
 #if NET_2_0
 		[ComVisible (false)]
 #else
@@ -866,10 +955,6 @@
 					bmp_g = null;
 				}
 				
-				if (invalid_region!=null) {
-					invalid_region.Dispose();
-					invalid_region=null;
-				}
 				if (this.InvokeRequired) {
 					if (Application.MessageLoop) {
 						this.BeginInvokeInternal(new MethodInvoker(DestroyHandle), null, true);
@@ -1007,39 +1092,23 @@
 
 		private void InvalidateBackBuffer ()
 		{
-			if (invalid_region != null)
-				invalid_region.Dispose();
-			invalid_region = new Region (ClientRectangle);
+			if (backbuffer != null)
+				backbuffer.Invalidate ();
 		}
 
-		private void CreateBackBuffer ()
+		private DoubleBuffer GetBackBuffer ()
 		{
-			if (backbuffer != null)
-				return;
-
-			int width = Width;
-			int height = Height;
-
-			if (width < 1) width = 1;
-			if (height < 1) height = 1;
-
-			XplatUI.CreateOffscreenDrawable (Handle, width, height, out backbuffer, out backbuffer_dc);
-			InvalidateBackBuffer ();
+			if (backbuffer == null)
+				backbuffer = new DoubleBuffer (this);
+			return backbuffer;
 		}
 
 		private void DisposeBackBuffer ()
 		{
-			if (backbuffer == null)
-				return;
-
-			XplatUI.DestroyOffscreenDrawable (backbuffer, backbuffer_dc);
-			backbuffer = null;
-			backbuffer_dc = null;
-
-
-			if (invalid_region != null)
-				invalid_region.Dispose ();
-			invalid_region = null;
+			if (backbuffer != null) {
+				backbuffer.Dispose ();
+				backbuffer = null;
+			}
 		}
 
 		internal static void SetChildColor(Control parent) {
@@ -4157,27 +4226,20 @@
 				if (paint_event == null) {
 					return;
 				}
-
-				if (invalid_region != null && !invalid_region.IsVisible (paint_event.ClipRectangle)) {
-
-					// Just blit the previous image
-					XplatUI.BlitFromOffscreen (Handle, paint_event.Graphics, backbuffer, backbuffer_dc, paint_event.ClipRectangle);
-					XplatUI.PaintEventEnd (Handle, true);
-					return;
-				}
-
-				Graphics dc = null;
-				Graphics back_dc = null;
-				object back = null;
+				DoubleBuffer current_buffer = null;
 				if (ThemeEngine.Current.DoubleBufferingSupported) {
 					if ((control_style & ControlStyles.DoubleBuffer) != 0) {
-						CreateBackBuffer ();
-						back = backbuffer;
-						back_dc = backbuffer_dc;
-						dc = paint_event.SetGraphics (back_dc);
+						current_buffer = GetBackBuffer ();
+						if (!current_buffer.InvalidRegion.IsVisible (paint_event.ClipRectangle)) {
+							// Just blit the previous image
+							current_buffer.Blit (paint_event);
+							XplatUI.PaintEventEnd (Handle, true);
+							return;
+						}
+						current_buffer.Start (paint_event);
 					}
 				}
-
+				
 				if (!GetStyle(ControlStyles.Opaque)) {
 					OnPaintBackground(paint_event);
 				}
@@ -4190,17 +4252,12 @@
 					OnPaint(paint_event);
 				}
 
-				if (ThemeEngine.Current.DoubleBufferingSupported)
-					if ((control_style & ControlStyles.DoubleBuffer) != 0) {
-						XplatUI.BlitFromOffscreen (Handle, dc, back, back_dc, paint_event.ClipRectangle);
-						paint_event.SetGraphics (dc);
-						invalid_region.Exclude (paint_event.ClipRectangle);
-
-						if (back != backbuffer)
-							XplatUI.DestroyOffscreenDrawable (back, back_dc);
-					}
-
+				if (current_buffer != null) {
+					current_buffer.End (paint_event);
+				}
+				
 				XplatUI.PaintEventEnd(Handle, true);
+				
 
 				return;
 			}
@@ -4738,10 +4795,7 @@
 						// invalid_region.IsVisible call) in
 						// the WM_PAINT handling below.
 						Rectangle r = Rectangle.Inflate(e.InvalidRect, 1,1);
-						if (invalid_region == null)
-							invalid_region = new Region (r);
-						else
-							invalid_region.Union (r);
+						backbuffer.InvalidRegion.Union (r);
 					}
 				}
 
Index: System.Windows.Forms/XplatUI.cs
===================================================================
--- System.Windows.Forms/XplatUI.cs	(revision 70171)
+++ System.Windows.Forms/XplatUI.cs	(working copy)
@@ -1000,26 +1000,31 @@
 		// double buffering
 		internal static void CreateOffscreenDrawable (IntPtr handle,
 							    int width, int height,
-							    out object offscreen_drawable,
-							    out Graphics offscreen_dc)
+							    out object offscreen_drawable)
 		{
 #if DriverDebug
 			Console.WriteLine("CreateOffscreenDrawable({2}, {0},{1}): Called", width, height, Window(handle));
 #endif
 			driver.CreateOffscreenDrawable (handle, width, height,
-							out offscreen_drawable,
-							out offscreen_dc);
+							out offscreen_drawable);
 		}
 
-		internal static void DestroyOffscreenDrawable (object offscreen_drawable,
-							     Graphics offscreen_dc)
+		internal static void DestroyOffscreenDrawable (object offscreen_drawable)
 		{
 #if DriverDebug
 			Console.WriteLine("DestroyOffscreenDrawable(): Called");
 #endif
-			driver.DestroyOffscreenDrawable (offscreen_drawable, offscreen_dc);
+			driver.DestroyOffscreenDrawable (offscreen_drawable);
 		}
 
+		internal static Graphics GetOffscreenGraphics (object offscreen_drawable)
+		{
+#if DriverDebug
+			Console.WriteLine("GetOffscreenGraphics(): Called");
+#endif
+			return driver.GetOffscreenGraphics (offscreen_drawable);
+		}
+
 		internal static void BlitFromOffscreen (IntPtr dest_handle,
 						      Graphics dest_dc,
 						      object offscreen_drawable,
Index: System.Windows.Forms/XplatUIDriver.cs
===================================================================
--- System.Windows.Forms/XplatUIDriver.cs	(revision 70171)
+++ System.Windows.Forms/XplatUIDriver.cs	(working copy)
@@ -293,23 +293,25 @@
 		// Double buffering
 		internal virtual void CreateOffscreenDrawable (IntPtr handle,
 							       int width, int height,
-							       out object offscreen_drawable,
-							       out Graphics offscreen_dc)
+							       out object offscreen_drawable)
 		{
 			Bitmap bmp = new Bitmap (width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
 
 			offscreen_drawable = bmp;
-			offscreen_dc = Graphics.FromImage (bmp);
 		}
 
-		internal virtual void DestroyOffscreenDrawable (object offscreen_drawable,
-								Graphics offscreen_dc)
+		internal virtual void DestroyOffscreenDrawable (object offscreen_drawable)
 		{
 			Bitmap bmp = (Bitmap)offscreen_drawable;
 
 			bmp.Dispose ();
-			offscreen_dc.Dispose ();
 		}
+		
+		internal virtual Graphics GetOffscreenGraphics (object offscreen_drawable)
+		{
+			Bitmap bmp = (Bitmap)offscreen_drawable;
+			return Graphics.FromImage (bmp);
+		}
 
 		internal virtual void BlitFromOffscreen (IntPtr dest_handle,
 							 Graphics dest_dc,
Index: System.Windows.Forms/XplatUIX11.cs
===================================================================
--- System.Windows.Forms/XplatUIX11.cs	(revision 70171)
+++ System.Windows.Forms/XplatUIX11.cs	(working copy)
@@ -5154,8 +5154,7 @@
 
 		internal override void CreateOffscreenDrawable (IntPtr handle,
 								int width, int height,
-								out object offscreen_drawable,
-								out Graphics offscreen_dc)
+								out object offscreen_drawable)
 		{
 			IntPtr root_out;
 			int x_out, y_out, width_out, height_out, border_width_out, depth_out;
@@ -5170,16 +5169,18 @@
 
 			offscreen_drawable = pixmap;
 
-			offscreen_dc = Graphics.FromHwnd (pixmap);
 		}
 
-		internal override void DestroyOffscreenDrawable (object offscreen_drawable,
-								 Graphics offscreen_dc)
+		internal override void DestroyOffscreenDrawable (object offscreen_drawable)
 		{
 			XFreePixmap (DisplayHandle, (IntPtr)offscreen_drawable);
-			offscreen_dc.Dispose ();
 		}
 
+		internal override Graphics GetOffscreenGraphics (object offscreen_drawable)
+		{
+			return Graphics.FromHwnd ((IntPtr) offscreen_drawable);
+		}
+		
 		internal override void BlitFromOffscreen (IntPtr dest_handle,
 							  Graphics dest_dc,
 							  object offscreen_drawable,
Index: System.Windows.Forms.X11Internal/X11Display.cs
===================================================================
--- System.Windows.Forms.X11Internal/X11Display.cs	(revision 70171)
+++ System.Windows.Forms.X11Internal/X11Display.cs	(working copy)
@@ -2416,8 +2416,7 @@
 		// double buffering support
 		public void CreateOffscreenDrawable (IntPtr handle,
 						     int width, int height,
-						     out object offscreen_drawable,
-						     out Graphics offscreen_dc)
+						     out object offscreen_drawable)
 		{
 			IntPtr root_out;
 			int x_out, y_out, width_out, height_out, border_width_out, depth_out;
@@ -2431,17 +2430,18 @@
 			IntPtr pixmap = Xlib.XCreatePixmap (display, handle, width, height, depth_out);
 
 			offscreen_drawable = pixmap;
-
-			offscreen_dc = Graphics.FromHwnd (pixmap);
 		}
 
-		public void DestroyOffscreenDrawable (object offscreen_drawable,
-						      Graphics offscreen_dc)
+		public void DestroyOffscreenDrawable (object offscreen_drawable)
 		{
 			Xlib.XFreePixmap (display, (IntPtr)offscreen_drawable);
-			offscreen_dc.Dispose ();
 		}
 
+		public Graphics GetOffscreenGraphics (object offscreen_drawable)
+		{
+			return Graphics.FromHwnd ((IntPtr) offscreen_drawable);
+		}
+
 		public void BlitFromOffscreen (IntPtr dest_handle,
 					       Graphics dest_dc,
 					       object offscreen_drawable,
Index: System.Windows.Forms.X11Internal/XplatUIX11-new.cs
===================================================================
--- System.Windows.Forms.X11Internal/XplatUIX11-new.cs	(revision 70171)
+++ System.Windows.Forms.X11Internal/XplatUIX11-new.cs	(working copy)
@@ -1026,20 +1026,22 @@
 
 		internal override void CreateOffscreenDrawable (IntPtr handle,
 								int width, int height,
-								out object offscreen_drawable,
-								out Graphics offscreen_dc)
+								out object offscreen_drawable)
 		{
 			display.CreateOffscreenDrawable (handle, width, height,
-							 out offscreen_drawable, out offscreen_dc);
+							 out offscreen_drawable);
 		}
 
-		internal override void DestroyOffscreenDrawable (object offscreen_drawable,
-								 Graphics offscreen_dc)
+		internal override void DestroyOffscreenDrawable (object offscreen_drawable)
 		{
-			display.DestroyOffscreenDrawable (offscreen_drawable,
-							  offscreen_dc);
+			display.DestroyOffscreenDrawable (offscreen_drawable);
 		}
 
+		internal override Graphics GetOffscreenGraphics (object offscreen_drawable)
+		{
+			return display.GetOffscreenGraphics (offscreen_drawable);
+		}
+
 		internal override void BlitFromOffscreen (IntPtr dest_handle,
 							  Graphics dest_dc,
 							  object offscreen_drawable,