Skip to content

Commit addf5a8

Browse files
authored
Merge 42a3744 into 72ee102
2 parents 72ee102 + 42a3744 commit addf5a8

File tree

6 files changed

+161
-279
lines changed

6 files changed

+161
-279
lines changed

CefSharp.Wpf/CefSharp.Wpf.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@
9696
<AppDesigner Include="Properties\" />
9797
<Compile Include="ChromiumWebBrowser.cs" />
9898
<Compile Include="PaintEventArgs.cs" />
99+
<Compile Include="Rendering\AbstractRenderHandler.cs" />
99100
<Compile Include="Rendering\Experimental\IncreaseBufferInteropRenderHandler.cs" />
100101
<Compile Include="Rendering\Experimental\ByteArrayWritableBitmapRenderHandler.cs" />
101102
<Compile Include="Rendering\InteropBitmapRenderHandler.cs" />
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
// Copyright © 2019 The CefSharp Authors. All rights reserved.
2+
//
3+
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
4+
5+
using System;
6+
using System.IO.MemoryMappedFiles;
7+
using System.Runtime.InteropServices;
8+
using System.Threading;
9+
using System.Windows;
10+
using System.Windows.Controls;
11+
using System.Windows.Media;
12+
using System.Windows.Threading;
13+
using Rect = CefSharp.Structs.Rect;
14+
15+
namespace CefSharp.Wpf.Rendering
16+
{
17+
/// <summary>
18+
/// Implements the basics of a <see cref="IRenderHandler"/>
19+
/// </summary>
20+
/// <seealso cref="CefSharp.Wpf.IRenderHandler" />
21+
public abstract class AbstractRenderHandler : IDisposable, IRenderHandler
22+
{
23+
[DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
24+
protected static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);
25+
26+
protected static readonly PixelFormat PixelFormat = PixelFormats.Pbgra32;
27+
protected static int BytesPerPixel = PixelFormat.BitsPerPixel / 8;
28+
29+
protected object lockObject = new object();
30+
31+
protected Size viewSize;
32+
protected Size popupSize;
33+
protected DispatcherPriority dispatcherPriority;
34+
35+
protected MemoryMappedFile viewMemoryMappedFile;
36+
protected MemoryMappedFile popupMemoryMappedFile;
37+
protected MemoryMappedViewAccessor viewMemoryMappedViewAccessor;
38+
protected MemoryMappedViewAccessor popupMemoryMappedViewAccessor;
39+
40+
/// <summary>
41+
/// The value for disposal, if it's 1 (one) then this instance is either disposed
42+
/// or in the process of getting disposed
43+
/// </summary>
44+
private int disposeSignaled;
45+
46+
/// <summary>
47+
/// Gets a value indicating whether this instance is disposed.
48+
/// </summary>
49+
/// <value><see langword="true"/> if this instance is disposed; otherwise, <see langword="true"/>.</value>
50+
public bool IsDisposed
51+
{
52+
get
53+
{
54+
return Interlocked.CompareExchange(ref disposeSignaled, 1, 1) == 1;
55+
}
56+
}
57+
58+
/// <summary>
59+
/// Releases all resources used by the <see cref="AbstractRenderHandler"/> object
60+
/// </summary>
61+
public void Dispose()
62+
{
63+
Dispose(true);
64+
GC.SuppressFinalize(this);
65+
}
66+
67+
/// <summary>
68+
/// Releases unmanaged and - optionally - managed resources for the <see cref="AbstractRenderHandler"/>
69+
/// </summary>
70+
/// <param name="disposing"><see langword="true" /> to release both managed and unmanaged resources; <see langword="false" /> to release only unmanaged resources.</param>
71+
protected virtual void Dispose(bool disposing)
72+
{
73+
if (Interlocked.CompareExchange(ref disposeSignaled, 1, 0) != 0)
74+
{
75+
return;
76+
}
77+
78+
if (!disposing)
79+
{
80+
return;
81+
}
82+
83+
ReleaseMemoryMappedView(ref popupMemoryMappedFile, ref popupMemoryMappedViewAccessor);
84+
ReleaseMemoryMappedView(ref viewMemoryMappedFile, ref viewMemoryMappedViewAccessor);
85+
}
86+
87+
protected void ReleaseMemoryMappedView(ref MemoryMappedFile mappedFile, ref MemoryMappedViewAccessor stream)
88+
{
89+
if (stream != null)
90+
{
91+
stream.Dispose();
92+
stream = null;
93+
}
94+
95+
if (mappedFile != null)
96+
{
97+
mappedFile.Dispose();
98+
mappedFile = null;
99+
}
100+
}
101+
102+
/// <summary>
103+
/// Called when an element has been rendered to the shared texture handle.
104+
/// This method is only called when <see cref="IWindowInfo.SharedTextureEnabled"/> is set to true
105+
/// </summary>
106+
/// <param name="isPopup">indicates whether the element is the view or the popup widget.</param>
107+
/// <param name="dirtyRect">contains the set of rectangles in pixel coordinates that need to be repainted</param>
108+
/// <param name="sharedHandle">is the handle for a D3D11 Texture2D that can be accessed via ID3D11Device using the OpenSharedResource method.</param>
109+
public virtual void OnAcceleratedPaint(bool isPopup, Rect dirtyRect, IntPtr sharedHandle)
110+
{
111+
// NOT USED
112+
}
113+
114+
/// <summary>
115+
/// Called when an element should be painted. (Invoked from CefRenderHandler.OnPaint)
116+
/// This method is only called when <see cref="IWindowInfo.SharedTextureEnabled"/> is set to false.
117+
/// </summary>
118+
/// <param name="isPopup">indicates whether the element is the view or the popup widget.</param>
119+
/// <param name="dirtyRect">contains the set of rectangles in pixel coordinates that need to be repainted</param>
120+
/// <param name="buffer">The bitmap will be will be width * height *4 bytes in size and represents a BGRA image with an upper-left origin</param>
121+
/// <param name="width">width</param>
122+
/// <param name="height">height</param>
123+
/// <param name="image">image used as parent for rendered bitmap</param>
124+
public virtual void OnPaint(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image)
125+
{
126+
if (image.Dispatcher.HasShutdownStarted)
127+
{
128+
return;
129+
}
130+
131+
if (isPopup)
132+
{
133+
CreateOrUpdateBitmap(isPopup, dirtyRect, buffer, width, height, image, ref popupSize, ref popupMemoryMappedFile, ref popupMemoryMappedViewAccessor);
134+
}
135+
else
136+
{
137+
CreateOrUpdateBitmap(isPopup, dirtyRect, buffer, width, height, image, ref viewSize, ref viewMemoryMappedFile, ref viewMemoryMappedViewAccessor);
138+
}
139+
}
140+
141+
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);
142+
}
143+
}

CefSharp.Wpf/Rendering/Experimental/ByteArrayWritableBitmapRenderHandler.cs

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@
33
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
44

55
using System;
6+
using System.IO.MemoryMappedFiles;
67
using System.Runtime.InteropServices;
78
using System.Windows;
89
using System.Windows.Controls;
9-
using System.Windows.Media;
1010
using System.Windows.Media.Imaging;
1111
using System.Windows.Threading;
12-
1312
using Rect = CefSharp.Structs.Rect;
1413

1514
namespace CefSharp.Wpf.Rendering.Experimental
@@ -21,18 +20,11 @@ namespace CefSharp.Wpf.Rendering.Experimental
2120
/// wise.
2221
/// </summary>
2322
/// <seealso cref="CefSharp.Wpf.IRenderHandler" />
24-
public class ByteArrayWritableBitmapRenderHandler : IRenderHandler
23+
public class ByteArrayWritableBitmapRenderHandler : AbstractRenderHandler
2524
{
26-
/// <summary>
27-
/// The pixel format
28-
/// </summary>
29-
private static readonly PixelFormat PixelFormat = PixelFormats.Prgba64;
30-
private static int BytesPerPixel = PixelFormat.BitsPerPixel / 8;
31-
3225
private double dpiX;
3326
private double dpiY;
3427
private bool invalidateDirtyRect;
35-
private DispatcherPriority dispatcherPriority;
3628

3729
/// <summary>
3830
/// Initializes a new instance of the <see cref="WritableBitmapRenderHandler"/> class.
@@ -49,25 +41,8 @@ public ByteArrayWritableBitmapRenderHandler(double dpiX, double dpiY, bool inval
4941
this.dispatcherPriority = dispatcherPriority;
5042
}
5143

52-
/// <summary>
53-
/// Called when an element has been rendered to the shared texture handle.
54-
/// This method is only called when <see cref="IWindowInfo.SharedTextureEnabled"/> is set to true
55-
/// </summary>
56-
/// <param name="isPopup">indicates whether the element is the view or the popup widget.</param>
57-
/// <param name="dirtyRect">contains the set of rectangles in pixel coordinates that need to be repainted</param>
58-
/// <param name="sharedHandle">is the handle for a D3D11 Texture2D that can be accessed via ID3D11Device using the OpenSharedResource method.</param>
59-
void IRenderHandler.OnAcceleratedPaint(bool isPopup, Rect dirtyRect, IntPtr sharedHandle)
44+
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)
6045
{
61-
//NOT USED
62-
}
63-
64-
void IRenderHandler.OnPaint(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image)
65-
{
66-
if (image.Dispatcher.HasShutdownStarted)
67-
{
68-
return;
69-
}
70-
7146
int pixels = width * height;
7247
int numberOfBytes = pixels * BytesPerPixel;
7348
var stride = width * BytesPerPixel;
@@ -117,10 +92,5 @@ void IRenderHandler.OnPaint(bool isPopup, Rect dirtyRect, IntPtr buffer, int wid
11792
}
11893
}), dispatcherPriority);
11994
}
120-
121-
void IDisposable.Dispose()
122-
{
123-
124-
}
12595
}
12696
}

CefSharp.Wpf/Rendering/Experimental/IncreaseBufferInteropRenderHandler.cs

Lines changed: 6 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@
44

55
using System;
66
using System.IO.MemoryMappedFiles;
7-
using System.Runtime.InteropServices;
87
using System.Windows;
98
using System.Windows.Controls;
109
using System.Windows.Interop;
11-
using System.Windows.Media;
1210
using System.Windows.Threading;
1311
using Rect = CefSharp.Structs.Rect;
1412

@@ -20,28 +18,8 @@ namespace CefSharp.Wpf.Rendering.Experimental
2018
/// when the size increases
2119
/// </summary>
2220
/// <seealso cref="CefSharp.Wpf.IRenderHandler" />
23-
public class IncreaseBufferInteropRenderHandler : IRenderHandler
21+
public class IncreaseBufferInteropRenderHandler : AbstractRenderHandler
2422
{
25-
[DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
26-
private static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);
27-
28-
/// <summary>
29-
/// The pixel format
30-
/// </summary>
31-
private static readonly PixelFormat PixelFormat = PixelFormats.Pbgra32;
32-
private static int BytesPerPixel = PixelFormat.BitsPerPixel / 8;
33-
34-
private object lockObject = new object();
35-
36-
private Size viewSize;
37-
private Size popupSize;
38-
private DispatcherPriority dispatcherPriority;
39-
40-
private MemoryMappedFile viewMemoryMappedFile;
41-
private MemoryMappedFile popupMemoryMappedFile;
42-
private MemoryMappedViewAccessor viewMemoryMappedViewAccessor;
43-
private MemoryMappedViewAccessor popupMemoryMappedViewAccessor;
44-
4523
/// <summary>
4624
/// Initializes a new instance of the <see cref="InteropBitmapRenderHandler"/> class.
4725
/// </summary>
@@ -51,46 +29,8 @@ public IncreaseBufferInteropRenderHandler(DispatcherPriority dispatcherPriority
5129
this.dispatcherPriority = dispatcherPriority;
5230
}
5331

54-
/// <summary>
55-
/// Dispose
56-
/// </summary>
57-
public void Dispose()
58-
{
59-
ReleaseMemoryMappedView(ref popupMemoryMappedFile, ref popupMemoryMappedViewAccessor);
60-
ReleaseMemoryMappedView(ref viewMemoryMappedFile, ref viewMemoryMappedViewAccessor);
61-
}
62-
63-
/// <summary>
64-
/// Called when an element has been rendered to the shared texture handle.
65-
/// This method is only called when <see cref="IWindowInfo.SharedTextureEnabled"/> is set to true
66-
/// </summary>
67-
/// <param name="isPopup">indicates whether the element is the view or the popup widget.</param>
68-
/// <param name="dirtyRect">contains the set of rectangles in pixel coordinates that need to be repainted</param>
69-
/// <param name="sharedHandle">is the handle for a D3D11 Texture2D that can be accessed via ID3D11Device using the OpenSharedResource method.</param>
70-
void IRenderHandler.OnAcceleratedPaint(bool isPopup, Rect dirtyRect, IntPtr sharedHandle)
71-
{
72-
//NOT USED
73-
}
74-
75-
void IRenderHandler.OnPaint(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image)
76-
{
77-
if (isPopup)
78-
{
79-
CreateOrUpdateBitmap(isPopup, dirtyRect, buffer, width, height, image, ref popupSize, ref popupMemoryMappedFile, ref popupMemoryMappedViewAccessor);
80-
}
81-
else
82-
{
83-
CreateOrUpdateBitmap(isPopup, dirtyRect, buffer, width, height, image, ref viewSize, ref viewMemoryMappedFile, ref viewMemoryMappedViewAccessor);
84-
}
85-
}
86-
87-
private void CreateOrUpdateBitmap(bool isPopup, Rect dirtyRect, IntPtr buffer, int width, int height, Image image, ref Size currentSize, ref MemoryMappedFile mappedFile, ref MemoryMappedViewAccessor viewAccessor)
32+
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)
8833
{
89-
if (image.Dispatcher.HasShutdownStarted)
90-
{
91-
return;
92-
}
93-
9434
var createNewBitmap = false;
9535

9636
lock (lockObject)
@@ -146,33 +86,15 @@ private void CreateOrUpdateBitmap(bool isPopup, Rect dirtyRect, IntPtr buffer, i
14686
var bitmap = (InteropBitmap)Imaging.CreateBitmapSourceFromMemorySection(backBufferHandle.DangerousGetHandle(), width, height, PixelFormat, stride, 0);
14787
image.Source = bitmap;
14888
}
149-
else
89+
else if (image.Source != null)
15090
{
151-
if (image.Source != null)
152-
{
153-
var sourceRect = new Int32Rect(dirtyRect.X, dirtyRect.Y, dirtyRect.Width, dirtyRect.Height);
154-
var bitmap = (InteropBitmap)image.Source;
155-
bitmap.Invalidate(sourceRect);
156-
}
91+
var sourceRect = new Int32Rect(dirtyRect.X, dirtyRect.Y, dirtyRect.Width, dirtyRect.Height);
92+
var bitmap = (InteropBitmap)image.Source;
93+
bitmap.Invalidate(sourceRect);
15794
}
15895
}
15996
}), dispatcherPriority);
16097
}
16198
}
162-
163-
private void ReleaseMemoryMappedView(ref MemoryMappedFile mappedFile, ref MemoryMappedViewAccessor stream)
164-
{
165-
if (stream != null)
166-
{
167-
stream.Dispose();
168-
stream = null;
169-
}
170-
171-
if (mappedFile != null)
172-
{
173-
mappedFile.Dispose();
174-
mappedFile = null;
175-
}
176-
}
17799
}
178100
}

0 commit comments

Comments
 (0)