diff --git a/CefSharp.Wpf/CefSharp.Wpf.csproj b/CefSharp.Wpf/CefSharp.Wpf.csproj
index f71f07899f..aad2fda87e 100644
--- a/CefSharp.Wpf/CefSharp.Wpf.csproj
+++ b/CefSharp.Wpf/CefSharp.Wpf.csproj
@@ -96,6 +96,7 @@
+
diff --git a/CefSharp.Wpf/Rendering/AbstractRenderHandler.cs b/CefSharp.Wpf/Rendering/AbstractRenderHandler.cs
new file mode 100644
index 0000000000..f7b2985133
--- /dev/null
+++ b/CefSharp.Wpf/Rendering/AbstractRenderHandler.cs
@@ -0,0 +1,143 @@
+// Copyright © 2019 The CefSharp Authors. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
+
+using System;
+using System.IO.MemoryMappedFiles;
+using System.Runtime.InteropServices;
+using System.Threading;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+using System.Windows.Threading;
+using Rect = CefSharp.Structs.Rect;
+
+namespace CefSharp.Wpf.Rendering
+{
+ ///
+ /// Implements the basics of a
+ ///
+ ///
+ public abstract class AbstractRenderHandler : IDisposable, IRenderHandler
+ {
+ [DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
+ protected static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);
+
+ protected static readonly PixelFormat PixelFormat = PixelFormats.Pbgra32;
+ protected static int BytesPerPixel = PixelFormat.BitsPerPixel / 8;
+
+ protected object lockObject = new object();
+
+ protected Size viewSize;
+ protected Size popupSize;
+ protected DispatcherPriority dispatcherPriority;
+
+ protected MemoryMappedFile viewMemoryMappedFile;
+ protected MemoryMappedFile popupMemoryMappedFile;
+ protected MemoryMappedViewAccessor viewMemoryMappedViewAccessor;
+ protected MemoryMappedViewAccessor popupMemoryMappedViewAccessor;
+
+ ///
+ /// The value for disposal, if it's 1 (one) then this instance is either disposed
+ /// or in the process of getting disposed
+ ///
+ private int disposeSignaled;
+
+ ///
+ /// Gets a value indicating whether this instance is disposed.
+ ///
+ /// if this instance is disposed; otherwise, .
+ public bool IsDisposed
+ {
+ get
+ {
+ return Interlocked.CompareExchange(ref disposeSignaled, 1, 1) == 1;
+ }
+ }
+
+ ///
+ /// Releases all resources used by the object
+ ///
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ ///
+ /// Releases unmanaged and - optionally - managed resources for the
+ ///
+ /// to release both managed and unmanaged resources; to release only unmanaged resources.
+ protected virtual void Dispose(bool disposing)
+ {
+ if (Interlocked.CompareExchange(ref disposeSignaled, 1, 0) != 0)
+ {
+ return;
+ }
+
+ if (!disposing)
+ {
+ return;
+ }
+
+ ReleaseMemoryMappedView(ref popupMemoryMappedFile, ref popupMemoryMappedViewAccessor);
+ ReleaseMemoryMappedView(ref viewMemoryMappedFile, ref viewMemoryMappedViewAccessor);
+ }
+
+ protected void ReleaseMemoryMappedView(ref MemoryMappedFile mappedFile, ref MemoryMappedViewAccessor stream)
+ {
+ if (stream != null)
+ {
+ stream.Dispose();
+ stream = null;
+ }
+
+ if (mappedFile != null)
+ {
+ mappedFile.Dispose();
+ mappedFile = null;
+ }
+ }
+
+ ///
+ /// Called when an element has been rendered to the shared texture handle.
+ /// This method is only called when is set to true
+ ///
+ /// indicates whether the element is the view or the popup widget.
+ /// contains the set of rectangles in pixel coordinates that need to be repainted
+ /// is the handle for a D3D11 Texture2D that can be accessed via ID3D11Device using the OpenSharedResource method.
+ public virtual void OnAcceleratedPaint(bool isPopup, Rect dirtyRect, IntPtr sharedHandle)
+ {
+ // NOT USED
+ }
+
+ ///
+ /// Called when an element should be painted. (Invoked from CefRenderHandler.OnPaint)
+ /// This method is only called when is set to false.
+ ///
+ /// indicates whether the element is the view or the popup widget.
+ /// contains the set of rectangles in pixel coordinates that need to be repainted
+ /// The bitmap will be will be width * height *4 bytes in size and represents a BGRA image with an upper-left origin
+ /// width
+ /// height
+ /// image used as parent for rendered bitmap
+ public virtual void OnPaint(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image)
+ {
+ if (image.Dispatcher.HasShutdownStarted)
+ {
+ return;
+ }
+
+ if (isPopup)
+ {
+ CreateOrUpdateBitmap(isPopup, dirtyRect, buffer, width, height, image, ref popupSize, ref popupMemoryMappedFile, ref popupMemoryMappedViewAccessor);
+ }
+ else
+ {
+ CreateOrUpdateBitmap(isPopup, dirtyRect, buffer, width, height, image, ref viewSize, ref viewMemoryMappedFile, ref viewMemoryMappedViewAccessor);
+ }
+ }
+
+ protected abstract void CreateOrUpdateBitmap(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image, ref Size currentSize, ref MemoryMappedFile mappedFile, ref MemoryMappedViewAccessor viewAccessor);
+ }
+}
diff --git a/CefSharp.Wpf/Rendering/Experimental/ByteArrayWritableBitmapRenderHandler.cs b/CefSharp.Wpf/Rendering/Experimental/ByteArrayWritableBitmapRenderHandler.cs
index 7df73e060a..2d84ce5300 100644
--- a/CefSharp.Wpf/Rendering/Experimental/ByteArrayWritableBitmapRenderHandler.cs
+++ b/CefSharp.Wpf/Rendering/Experimental/ByteArrayWritableBitmapRenderHandler.cs
@@ -3,13 +3,12 @@
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
using System;
+using System.IO.MemoryMappedFiles;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
-using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
-
using Rect = CefSharp.Structs.Rect;
namespace CefSharp.Wpf.Rendering.Experimental
@@ -21,18 +20,11 @@ namespace CefSharp.Wpf.Rendering.Experimental
/// wise.
///
///
- public class ByteArrayWritableBitmapRenderHandler : IRenderHandler
+ public class ByteArrayWritableBitmapRenderHandler : AbstractRenderHandler
{
- ///
- /// The pixel format
- ///
- private static readonly PixelFormat PixelFormat = PixelFormats.Prgba64;
- private static int BytesPerPixel = PixelFormat.BitsPerPixel / 8;
-
private double dpiX;
private double dpiY;
private bool invalidateDirtyRect;
- private DispatcherPriority dispatcherPriority;
///
/// Initializes a new instance of the class.
@@ -49,25 +41,8 @@ public ByteArrayWritableBitmapRenderHandler(double dpiX, double dpiY, bool inval
this.dispatcherPriority = dispatcherPriority;
}
- ///
- /// Called when an element has been rendered to the shared texture handle.
- /// This method is only called when is set to true
- ///
- /// indicates whether the element is the view or the popup widget.
- /// contains the set of rectangles in pixel coordinates that need to be repainted
- /// is the handle for a D3D11 Texture2D that can be accessed via ID3D11Device using the OpenSharedResource method.
- void IRenderHandler.OnAcceleratedPaint(bool isPopup, Rect dirtyRect, IntPtr sharedHandle)
+ protected override void CreateOrUpdateBitmap(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image, ref Size currentSize, ref MemoryMappedFile mappedFile, ref MemoryMappedViewAccessor viewAccessor)
{
- //NOT USED
- }
-
- void IRenderHandler.OnPaint(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image)
- {
- if (image.Dispatcher.HasShutdownStarted)
- {
- return;
- }
-
int pixels = width * height;
int numberOfBytes = pixels * BytesPerPixel;
var stride = width * BytesPerPixel;
@@ -117,10 +92,5 @@ void IRenderHandler.OnPaint(bool isPopup, Rect dirtyRect, IntPtr buffer, int wid
}
}), dispatcherPriority);
}
-
- void IDisposable.Dispose()
- {
-
- }
}
}
diff --git a/CefSharp.Wpf/Rendering/Experimental/IncreaseBufferInteropRenderHandler.cs b/CefSharp.Wpf/Rendering/Experimental/IncreaseBufferInteropRenderHandler.cs
index 46f18a319b..d5bcab284d 100644
--- a/CefSharp.Wpf/Rendering/Experimental/IncreaseBufferInteropRenderHandler.cs
+++ b/CefSharp.Wpf/Rendering/Experimental/IncreaseBufferInteropRenderHandler.cs
@@ -4,11 +4,9 @@
using System;
using System.IO.MemoryMappedFiles;
-using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interop;
-using System.Windows.Media;
using System.Windows.Threading;
using Rect = CefSharp.Structs.Rect;
@@ -20,28 +18,8 @@ namespace CefSharp.Wpf.Rendering.Experimental
/// when the size increases
///
///
- public class IncreaseBufferInteropRenderHandler : IRenderHandler
+ public class IncreaseBufferInteropRenderHandler : AbstractRenderHandler
{
- [DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
- private static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);
-
- ///
- /// The pixel format
- ///
- private static readonly PixelFormat PixelFormat = PixelFormats.Pbgra32;
- private static int BytesPerPixel = PixelFormat.BitsPerPixel / 8;
-
- private object lockObject = new object();
-
- private Size viewSize;
- private Size popupSize;
- private DispatcherPriority dispatcherPriority;
-
- private MemoryMappedFile viewMemoryMappedFile;
- private MemoryMappedFile popupMemoryMappedFile;
- private MemoryMappedViewAccessor viewMemoryMappedViewAccessor;
- private MemoryMappedViewAccessor popupMemoryMappedViewAccessor;
-
///
/// Initializes a new instance of the class.
///
@@ -51,46 +29,8 @@ public IncreaseBufferInteropRenderHandler(DispatcherPriority dispatcherPriority
this.dispatcherPriority = dispatcherPriority;
}
- ///
- /// Dispose
- ///
- public void Dispose()
- {
- ReleaseMemoryMappedView(ref popupMemoryMappedFile, ref popupMemoryMappedViewAccessor);
- ReleaseMemoryMappedView(ref viewMemoryMappedFile, ref viewMemoryMappedViewAccessor);
- }
-
- ///
- /// Called when an element has been rendered to the shared texture handle.
- /// This method is only called when is set to true
- ///
- /// indicates whether the element is the view or the popup widget.
- /// contains the set of rectangles in pixel coordinates that need to be repainted
- /// is the handle for a D3D11 Texture2D that can be accessed via ID3D11Device using the OpenSharedResource method.
- void IRenderHandler.OnAcceleratedPaint(bool isPopup, Rect dirtyRect, IntPtr sharedHandle)
- {
- //NOT USED
- }
-
- void IRenderHandler.OnPaint(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image)
- {
- if (isPopup)
- {
- CreateOrUpdateBitmap(isPopup, dirtyRect, buffer, width, height, image, ref popupSize, ref popupMemoryMappedFile, ref popupMemoryMappedViewAccessor);
- }
- else
- {
- CreateOrUpdateBitmap(isPopup, dirtyRect, buffer, width, height, image, ref viewSize, ref viewMemoryMappedFile, ref viewMemoryMappedViewAccessor);
- }
- }
-
- private void CreateOrUpdateBitmap(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image, ref Size currentSize, ref MemoryMappedFile mappedFile, ref MemoryMappedViewAccessor viewAccessor)
+ protected override void CreateOrUpdateBitmap(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image, ref Size currentSize, ref MemoryMappedFile mappedFile, ref MemoryMappedViewAccessor viewAccessor)
{
- if (image.Dispatcher.HasShutdownStarted)
- {
- return;
- }
-
var createNewBitmap = false;
lock (lockObject)
@@ -146,33 +86,15 @@ private void CreateOrUpdateBitmap(bool isPopup, Rect dirtyRect, IntPtr buffer, i
var bitmap = (InteropBitmap)Imaging.CreateBitmapSourceFromMemorySection(backBufferHandle.DangerousGetHandle(), width, height, PixelFormat, stride, 0);
image.Source = bitmap;
}
- else
+ else if (image.Source != null)
{
- if (image.Source != null)
- {
- var sourceRect = new Int32Rect(dirtyRect.X, dirtyRect.Y, dirtyRect.Width, dirtyRect.Height);
- var bitmap = (InteropBitmap)image.Source;
- bitmap.Invalidate(sourceRect);
- }
+ var sourceRect = new Int32Rect(dirtyRect.X, dirtyRect.Y, dirtyRect.Width, dirtyRect.Height);
+ var bitmap = (InteropBitmap)image.Source;
+ bitmap.Invalidate(sourceRect);
}
}
}), dispatcherPriority);
}
}
-
- private void ReleaseMemoryMappedView(ref MemoryMappedFile mappedFile, ref MemoryMappedViewAccessor stream)
- {
- if (stream != null)
- {
- stream.Dispose();
- stream = null;
- }
-
- if (mappedFile != null)
- {
- mappedFile.Dispose();
- mappedFile = null;
- }
- }
}
}
diff --git a/CefSharp.Wpf/Rendering/InteropBitmapRenderHandler.cs b/CefSharp.Wpf/Rendering/InteropBitmapRenderHandler.cs
index cef266207c..c6fbbd3d00 100644
--- a/CefSharp.Wpf/Rendering/InteropBitmapRenderHandler.cs
+++ b/CefSharp.Wpf/Rendering/InteropBitmapRenderHandler.cs
@@ -4,11 +4,9 @@
using System;
using System.IO.MemoryMappedFiles;
-using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interop;
-using System.Windows.Media;
using System.Windows.Threading;
using Rect = CefSharp.Structs.Rect;
@@ -20,28 +18,8 @@ namespace CefSharp.Wpf.Rendering
/// or creates a new InteropBitmap when required
///
///
- public class InteropBitmapRenderHandler : IRenderHandler
+ public class InteropBitmapRenderHandler : AbstractRenderHandler
{
- [DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
- private static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);
-
- ///
- /// The pixel format
- ///
- private static readonly PixelFormat PixelFormat = PixelFormats.Pbgra32;
- private static int BytesPerPixel = PixelFormat.BitsPerPixel / 8;
-
- private object lockObject = new object();
-
- private Size viewSize;
- private Size popupSize;
- private DispatcherPriority dispatcherPriority;
-
- private MemoryMappedFile viewMemoryMappedFile;
- private MemoryMappedFile popupMemoryMappedFile;
- private MemoryMappedViewAccessor viewMemoryMappedViewAccessor;
- private MemoryMappedViewAccessor popupMemoryMappedViewAccessor;
-
///
/// Initializes a new instance of the class.
///
@@ -51,46 +29,8 @@ public InteropBitmapRenderHandler(DispatcherPriority dispatcherPriority = Dispat
this.dispatcherPriority = dispatcherPriority;
}
- ///
- /// Dispose
- ///
- public void Dispose()
- {
- ReleaseMemoryMappedView(ref popupMemoryMappedFile, ref popupMemoryMappedViewAccessor);
- ReleaseMemoryMappedView(ref viewMemoryMappedFile, ref viewMemoryMappedViewAccessor);
- }
-
- ///
- /// Called when an element has been rendered to the shared texture handle.
- /// This method is only called when is set to true
- ///
- /// indicates whether the element is the view or the popup widget.
- /// contains the set of rectangles in pixel coordinates that need to be repainted
- /// is the handle for a D3D11 Texture2D that can be accessed via ID3D11Device using the OpenSharedResource method.
- void IRenderHandler.OnAcceleratedPaint(bool isPopup, Rect dirtyRect, IntPtr sharedHandle)
- {
- //NOT USED
- }
-
- void IRenderHandler.OnPaint(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image)
- {
- if (isPopup)
- {
- CreateOrUpdateBitmap(isPopup, dirtyRect, buffer, width, height, image, ref popupSize, ref popupMemoryMappedFile, ref popupMemoryMappedViewAccessor);
- }
- else
- {
- CreateOrUpdateBitmap(isPopup, dirtyRect, buffer, width, height, image, ref viewSize, ref viewMemoryMappedFile, ref viewMemoryMappedViewAccessor);
- }
- }
-
- private void CreateOrUpdateBitmap(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image, ref Size currentSize, ref MemoryMappedFile mappedFile, ref MemoryMappedViewAccessor viewAccessor)
+ protected override void CreateOrUpdateBitmap(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image, ref Size currentSize, ref MemoryMappedFile mappedFile, ref MemoryMappedViewAccessor viewAccessor)
{
- if (image.Dispatcher.HasShutdownStarted)
- {
- return;
- }
-
var createNewBitmap = false;
lock (lockObject)
@@ -142,33 +82,15 @@ private void CreateOrUpdateBitmap(bool isPopup, Rect dirtyRect, IntPtr buffer, i
var bitmap = (InteropBitmap)Imaging.CreateBitmapSourceFromMemorySection(backBufferHandle.DangerousGetHandle(), width, height, PixelFormat, stride, 0);
image.Source = bitmap;
}
- else
+ else if (image.Source != null)
{
- if (image.Source != null)
- {
- var sourceRect = new Int32Rect(dirtyRect.X, dirtyRect.Y, dirtyRect.Width, dirtyRect.Height);
- var bitmap = (InteropBitmap)image.Source;
- bitmap.Invalidate(sourceRect);
- }
+ var sourceRect = new Int32Rect(dirtyRect.X, dirtyRect.Y, dirtyRect.Width, dirtyRect.Height);
+ var bitmap = (InteropBitmap)image.Source;
+ bitmap.Invalidate(sourceRect);
}
}
}), dispatcherPriority);
}
}
-
- private void ReleaseMemoryMappedView(ref MemoryMappedFile mappedFile, ref MemoryMappedViewAccessor stream)
- {
- if (stream != null)
- {
- stream.Dispose();
- stream = null;
- }
-
- if (mappedFile != null)
- {
- mappedFile.Dispose();
- mappedFile = null;
- }
- }
}
}
diff --git a/CefSharp.Wpf/Rendering/WritableBitmapRenderHandler.cs b/CefSharp.Wpf/Rendering/WritableBitmapRenderHandler.cs
index 5b7eef343c..b300d3fd06 100644
--- a/CefSharp.Wpf/Rendering/WritableBitmapRenderHandler.cs
+++ b/CefSharp.Wpf/Rendering/WritableBitmapRenderHandler.cs
@@ -4,13 +4,10 @@
using System;
using System.IO.MemoryMappedFiles;
-using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
-using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
-
using Rect = CefSharp.Structs.Rect;
namespace CefSharp.Wpf.Rendering
@@ -21,30 +18,11 @@ namespace CefSharp.Wpf.Rendering
/// or creates a new WritableBitmap when required
///
///
- public class WritableBitmapRenderHandler : IRenderHandler
+ public class WritableBitmapRenderHandler : AbstractRenderHandler
{
- [DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
- private static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);
-
- ///
- /// The pixel format
- ///
- private static readonly PixelFormat PixelFormat = PixelFormats.Pbgra32;
- private static int BytesPerPixel = PixelFormat.BitsPerPixel / 8;
-
- private object lockObject = new object();
-
- private Size viewSize;
- private Size popupSize;
private double dpiX;
private double dpiY;
private bool invalidateDirtyRect;
- private DispatcherPriority dispatcherPriority;
-
- private MemoryMappedFile viewMemoryMappedFile;
- private MemoryMappedFile popupMemoryMappedFile;
- private MemoryMappedViewAccessor viewMemoryMappedViewAccessor;
- private MemoryMappedViewAccessor popupMemoryMappedViewAccessor;
///
/// Initializes a new instance of the class.
@@ -61,51 +39,12 @@ public WritableBitmapRenderHandler(double dpiX, double dpiY, bool invalidateDirt
this.dispatcherPriority = dispatcherPriority;
}
- ///
- /// Dispose
- ///
- public void Dispose()
- {
- ReleaseMemoryMappedView(ref popupMemoryMappedFile, ref popupMemoryMappedViewAccessor);
- ReleaseMemoryMappedView(ref viewMemoryMappedFile, ref viewMemoryMappedViewAccessor);
- }
-
- ///
- /// Called when an element has been rendered to the shared texture handle.
- /// This method is only called when is set to true
- ///
- /// indicates whether the element is the view or the popup widget.
- /// contains the set of rectangles in pixel coordinates that need to be repainted
- /// is the handle for a D3D11 Texture2D that can be accessed via ID3D11Device using the OpenSharedResource method.
- void IRenderHandler.OnAcceleratedPaint(bool isPopup, Rect dirtyRect, IntPtr sharedHandle)
- {
- //NOT USED
- }
-
- void IRenderHandler.OnPaint(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image)
- {
- if (isPopup)
- {
- CreateOrUpdateBitmap(isPopup, dirtyRect, buffer, width, height, image, ref popupSize, ref popupMemoryMappedFile, ref popupMemoryMappedViewAccessor);
- }
- else
- {
- CreateOrUpdateBitmap(isPopup, dirtyRect, buffer, width, height, image, ref viewSize, ref viewMemoryMappedFile, ref viewMemoryMappedViewAccessor);
- }
- }
-
- private void CreateOrUpdateBitmap(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image, ref Size currentSize, ref MemoryMappedFile mappedFile, ref MemoryMappedViewAccessor viewAccessor)
+ protected override void CreateOrUpdateBitmap(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image, ref Size currentSize, ref MemoryMappedFile mappedFile, ref MemoryMappedViewAccessor viewAccessor)
{
bool createNewBitmap = false;
- if (image.Dispatcher.HasShutdownStarted)
- {
- return;
- }
-
lock (lockObject)
{
-
int pixels = width * height;
int numberOfBytes = pixels * BytesPerPixel;
@@ -181,20 +120,5 @@ private void CreateOrUpdateBitmap(bool isPopup, Rect dirtyRect, IntPtr buffer, i
}), dispatcherPriority);
}
}
-
- private void ReleaseMemoryMappedView(ref MemoryMappedFile mappedFile, ref MemoryMappedViewAccessor stream)
- {
- if (stream != null)
- {
- stream.Dispose();
- stream = null;
- }
-
- if (mappedFile != null)
- {
- mappedFile.Dispose();
- mappedFile = null;
- }
- }
}
}