Skip to content

Commit bb56109

Browse files
author
Steal
authored
Merge pull request #1 from sokcuri/master
Direct Render to GDI
2 parents 9311824 + 8bafabb commit bb56109

File tree

4 files changed

+121
-83
lines changed

4 files changed

+121
-83
lines changed

Layered2D/Interop/UnsafeNativeMethods.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,10 @@ public struct BITMAPV5HEADER
135135
public int bV5YPelsPerMeter;
136136
public uint bV5ClrUsed;
137137
public uint bV5ClrImportant;
138-
public uint bV5RedMask;
139-
public uint bV5GreenMask;
140-
public uint bV5BlueMask;
141-
public uint bV5AlphaMask;
138+
public ColorMask bV5RedMask;
139+
public ColorMask bV5GreenMask;
140+
public ColorMask bV5BlueMask;
141+
public ColorMask bV5AlphaMask;
142142
public uint bV5CSType;
143143
public CIEXYZTRIPLE bV5Endpoints;
144144
public uint bV5GammaRed;
@@ -270,5 +270,14 @@ public enum WindowLongFlags : int
270270
DWLP_MSGRESULT = 0x0,
271271
DWLP_DLGPROC = 0x4
272272
}
273+
274+
[Flags]
275+
public enum ColorMask : uint
276+
{
277+
Alpha = 0xFF000000,
278+
Red = 0x00FF0000,
279+
Green = 0x0000FF00,
280+
Blue = 0x000000FF
281+
}
273282
}
274283
}

Layered2D/LayeredBuffer.cs

Lines changed: 95 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,117 @@
1-
using SkiaSharp;
1+
using System;
2+
using SkiaSharp;
3+
using System.Runtime.InteropServices;
24
using static Layered2D.Interop.UnsafeNativeMethods;
35

46
namespace Layered2D
57
{
68
public class LayeredBuffer
79
{
10+
#region [ Property ]
11+
public SKColorType ColorType { get; }
12+
public SKAlphaType AlphaType { get; }
13+
#endregion
14+
15+
#region [ Resources ]
816
internal SKBitmap Bitmap { get; set; }
917
internal RawSize Size { get; private set; }
1018

19+
internal IntPtr screenDc;
20+
internal IntPtr memDc;
21+
internal IntPtr native;
22+
internal IntPtr scan0;
23+
internal IntPtr oldBitmap;
24+
25+
internal BLENDFUNCTION blendFunc;
26+
#endregion
27+
28+
#region [ Initializer ]
1129
public LayeredBuffer(int width, int height, SKColorType colorType, SKAlphaType alphaType)
1230
{
1331
this.Size = new RawSize(width, height);
32+
this.ColorType = colorType;
33+
this.AlphaType = alphaType;
1434

15-
this.Bitmap = new SKBitmap(width, height, colorType, alphaType);
35+
Initialize();
1636
}
1737

38+
private void Initialize()
39+
{
40+
this.Bitmap = new SKBitmap();
41+
42+
SwapChain();
43+
}
44+
#endregion
45+
46+
#region [ User Methods ]
1847
public void Resize(int width, int height)
1948
{
2049
this.Size = new RawSize(width, height);
2150

22-
var info = this.Bitmap.Info;
23-
this.Bitmap.Dispose();
24-
this.Bitmap = new SKBitmap(width, height, info.ColorType, info.AlphaType);
51+
ReleaseResources();
52+
SwapChain();
53+
}
54+
#endregion
55+
56+
#region [ Context Handling ]
57+
private void SwapChain()
58+
{
59+
CreateNativeContext();
60+
61+
var info = new SKImageInfo(
62+
Size.Width,
63+
Size.Height,
64+
SKColorType.Bgra8888,
65+
SKAlphaType.Premul);
66+
67+
var result = this.Bitmap.InstallPixels(
68+
info, scan0,
69+
info.RowBytes,
70+
null, null,
71+
"RELEASING");
72+
}
73+
74+
private void ReleaseResources()
75+
{
76+
ReleaseDC(IntPtr.Zero, screenDc);
77+
SelectObject(memDc, oldBitmap);
78+
DeleteDC(memDc);
79+
80+
DeleteObject(native);
81+
DeleteObject(scan0);
82+
DeleteObject(oldBitmap);
83+
}
84+
85+
internal void CreateNativeContext()
86+
{
87+
var bmh = new BITMAPV5HEADER()
88+
{
89+
bV5Size = (uint)Marshal.SizeOf(typeof(BITMAPV5HEADER)),
90+
bV5Width = Size.Width,
91+
bV5Height = -Size.Height,
92+
bV5Planes = 1,
93+
bV5BitCount = 32,
94+
bV5Compression = BitmapCompressionMode.BI_RGB,
95+
bV5AlphaMask = ColorMask.Alpha,
96+
bV5RedMask = ColorMask.Red,
97+
bV5GreenMask = ColorMask.Green,
98+
bV5BlueMask = ColorMask.Blue
99+
};
100+
101+
blendFunc = new BLENDFUNCTION()
102+
{
103+
BlendOp = AC_SRC_OVER,
104+
BlendFlags = 0,
105+
SourceConstantAlpha = 255,
106+
AlphaFormat = AC_SRC_ALPHA
107+
};
108+
109+
screenDc = GetDC(IntPtr.Zero);
110+
memDc = CreateCompatibleDC(screenDc);
111+
112+
native = CreateDIBSection(screenDc, ref bmh, 0, out scan0, IntPtr.Zero, 0);
113+
oldBitmap = SelectObject(memDc, native);
25114
}
115+
#endregion
26116
}
27117
}

Layered2D/LayeredContext.cs

Lines changed: 7 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,36 @@
11
using System;
22
using SkiaSharp;
3-
using System.Runtime.InteropServices;
43
using static Layered2D.Interop.UnsafeNativeMethods;
54

65
namespace Layered2D
76
{
87
public class LayeredContext : SKCanvas
98
{
10-
internal RawPoint targetPosition;
11-
129
RawPoint emptyPoint = new RawPoint(0, 0);
13-
RawSize screenSize;
1410

15-
LayeredBuffer buffer;
16-
BLENDFUNCTION blendFunc;
11+
internal RawPoint targetPosition;
1712

1813
IntPtr target;
19-
IntPtr native;
20-
IntPtr scan0;
21-
22-
IntPtr oldBitmap;
23-
IntPtr screenDc;
24-
IntPtr memDc;
14+
LayeredBuffer buffer;
2515

2616
public LayeredContext(IntPtr target, LayeredBuffer buffer) : base(buffer.Bitmap)
2717
{
2818
this.target = target;
2919
this.buffer = buffer;
30-
31-
Initialize();
32-
}
33-
34-
private void Initialize()
35-
{
36-
var bmh = new BITMAPV5HEADER()
37-
{
38-
bV5Size = (uint)Marshal.SizeOf(typeof(BITMAPV5HEADER)),
39-
bV5Width = buffer.Bitmap.Width,
40-
bV5Height = -buffer.Bitmap.Height,
41-
bV5Planes = 1,
42-
bV5BitCount = 32,
43-
bV5Compression = BitmapCompressionMode.BI_RGB,
44-
bV5AlphaMask = 0xFF000000,
45-
bV5RedMask = 0x00FF0000,
46-
bV5GreenMask = 0x0000FF00,
47-
bV5BlueMask = 0x000000FF
48-
};
49-
50-
blendFunc = new BLENDFUNCTION()
51-
{
52-
BlendOp = AC_SRC_OVER,
53-
BlendFlags = 0,
54-
SourceConstantAlpha = 255,
55-
AlphaFormat = AC_SRC_ALPHA
56-
};
57-
58-
screenSize = new RawSize(buffer.Bitmap.Width, buffer.Bitmap.Height);
59-
60-
screenDc = GetDC(IntPtr.Zero);
61-
memDc = CreateCompatibleDC(screenDc);
62-
63-
native = CreateDIBSection(screenDc, ref bmh, 0, out scan0, IntPtr.Zero, 0);
64-
oldBitmap = SelectObject(memDc, native);
6520
}
6621

6722
public void Present()
6823
{
69-
buffer.Bitmap.CopyPixelsTo(scan0, buffer.Bitmap.ByteCount);
70-
24+
var screenSize = buffer.Size;
25+
7126
UpdateLayeredWindow(
7227
target,
73-
screenDc,
28+
buffer.screenDc,
7429
ref targetPosition, ref screenSize,
75-
memDc,
30+
buffer.memDc,
7631
ref emptyPoint, 0,
77-
ref blendFunc,
32+
ref buffer.blendFunc,
7833
ULW_ALPHA);
7934
}
80-
81-
protected override void Dispose(bool disposing)
82-
{
83-
base.Dispose(disposing);
84-
85-
ReleaseDC(IntPtr.Zero, screenDc);
86-
SelectObject(memDc, oldBitmap);
87-
DeleteDC(memDc);
88-
89-
DeleteObject(native);
90-
DeleteObject(scan0);
91-
DeleteObject(oldBitmap);
92-
}
9335
}
9436
}

Layered2D/Windows/LayeredWindow.cs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
using System.Drawing;
33
using System.Windows.Forms;
44
using System.ComponentModel;
5+
56
using SkiaSharp;
7+
using SkiaSharp.Views.Desktop;
68

79
using WS = Layered2D.Interop.UnsafeNativeMethods.WindowStyles;
8-
using System.Threading;
9-
using SkiaSharp.Views.Desktop;
1010

1111
namespace Layered2D.Windows
1212
{
@@ -176,7 +176,7 @@ protected override void CreateHandle()
176176
}
177177

178178
#endregion
179-
179+
180180
#region [ Update ]
181181
protected override void OnLoad(EventArgs e)
182182
{
@@ -213,15 +213,12 @@ private void SetResolutionCore()
213213
if (isLoaded)
214214
{
215215
this.SuspendLayout();
216-
216+
217217
buffer.Resize(Width, Height);
218-
219-
var contextPosition = context.targetPosition;
220-
218+
221219
context.Dispose();
222220
context = new LayeredContext(this.Handle, buffer);
223-
context.targetPosition = contextPosition;
224-
221+
225222
this.Render();
226223

227224
this.NativeWidth = this.Width;

0 commit comments

Comments
 (0)