rendered paste bodyIndex: 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,