From d32b6ef87f9dd34751c2b2469c9937203273244b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=96=B0=E6=97=A0=E6=AD=A2=E7=AB=9E?= <734913414@qq.com> Date: Tue, 18 Jun 2024 11:17:07 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=81=E8=AE=B8=E5=A4=8D=E7=94=A8Context=20?= =?UTF-8?q?=E5=9C=A8=E5=86=85=E5=AD=98=E6=AF=94=E8=BE=83=E5=B0=8F=E7=9A=84?= =?UTF-8?q?=E6=97=A7=E7=94=B5=E8=84=91=E4=B8=8A=EF=BC=8C=E5=9C=A8=E8=B0=83?= =?UTF-8?q?=E7=94=A8=20var=20bitmap=20=3D=20new=20SKBitmap(BITMAP.bmWidth,?= =?UTF-8?q?=20BITMAP.bmHeight);=E6=97=B6=20=E4=BC=9A=E5=9B=A0=E4=B8=BASKBi?= =?UTF-8?q?tmap.TryAllocPixels=20=E9=9A=8F=E6=9C=BA=E5=87=BA=E7=8E=B0Syste?= =?UTF-8?q?m.Exception:=20Unable=20to=20allocate=20pixels=20for=20the=20bi?= =?UTF-8?q?tmap.=20=20=20=E5=A4=8D=E7=94=A8Context=EF=BC=8C=E5=87=8F?= =?UTF-8?q?=E5=B0=8FSKBitmap.TryAllocPixels=20=E8=B0=83=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CPF.Skia/SkiaDrawingContext.cs | 33 +++++++++++++++++++++++++++++++++ CPF.Windows/WindowImpl.cs | 26 +++++++++++++++++++++++--- CPF/Drawing/DrawingContext.cs | 9 +++++++++ 3 files changed, 65 insertions(+), 3 deletions(-) diff --git a/CPF.Skia/SkiaDrawingContext.cs b/CPF.Skia/SkiaDrawingContext.cs index d156a44..62005e2 100644 --- a/CPF.Skia/SkiaDrawingContext.cs +++ b/CPF.Skia/SkiaDrawingContext.cs @@ -128,6 +128,39 @@ namespace CPF.Skia canvas = new SKCanvas(this.bitmap); } + public override bool ResetHdcCanvas(IRenderTarget renderTarget) + { + IntPtr hdc = IntPtr.Zero; + if (renderTarget is HDCRenderTarget hDC) + { + hdc = hDC.Hdc; + } + else if (renderTarget is OpenGlRenderTarget open) + { + hdc = open.FailBackTarget; + } + if (hdc == IntPtr.Zero) + { + return false; + } + + //获取dc里的位图信息,Windows平台 + var hbitmap = UnmanagedMethods.GetCurrentObject(hdc, ObjectType.OBJ_BITMAP); + BITMAP BITMAP = new BITMAP(); + UnmanagedMethods.GetObject(hbitmap, Marshal.SizeOf(typeof(BITMAP)), BITMAP); + if (bitmap == null || bitmap.Width != BITMAP.bmWidth || bitmap.Height != BITMAP.bmHeight) + { + return false; + } + + canvas.Flush(); + canvas.Dispose(); + canvas = null; + bitmap.SetPixels(BITMAP.bmBits); + canvas = new SKCanvas(this.bitmap); + return true; + } + //public SkiaDrawingContext(SKBitmap bitmap) //{ // this.bitmap = bitmap; diff --git a/CPF.Windows/WindowImpl.cs b/CPF.Windows/WindowImpl.cs index eeb31fe..c0116e2 100644 --- a/CPF.Windows/WindowImpl.cs +++ b/CPF.Windows/WindowImpl.cs @@ -939,6 +939,10 @@ namespace CPF.Windows // gl.PopMatrix(); // gl.Flush(); //} + + IRenderTarget lastRenderTarget; + DrawingContext cacheDC; + void OnPaint(IntPtr hdc, Rect rect) { if (handle == IntPtr.Zero) @@ -1013,10 +1017,26 @@ namespace CPF.Windows wglContext.GetFramebufferInfo(out var fb, out var sam, out var sten); rt = new OpenGlRenderTarget(hdc, wglContext, (int)Bounds.Width, (int)Bounds.Height, fb, sam, sten); } - //Console.WriteLine(rt + " " + isLayered + " " + useGPU + " " + memDc); - using (DrawingContext dc = DrawingContext.FromRenderTarget(rt)) + + if (lastRenderTarget == null || lastRenderTarget.Width != rt.Width || lastRenderTarget.Height != rt.Height) { - root.RenderView(dc, rect); + lastRenderTarget = rt; + if (cacheDC != null) + { + cacheDC.Dispose(); + cacheDC = null; + } + } + + if (cacheDC == null || !cacheDC.ResetHdcCanvas(rt)) + { + cacheDC = DrawingContext.FromRenderTarget(rt); + } + + //Console.WriteLine(rt + " " + isLayered + " " + useGPU + " " + memDc); + //using (DrawingContext dc = DrawingContext.FromRenderTarget(rt)) + { + root.RenderView(cacheDC, rect); //DrawRenderRectangle(dc); } //testPaint(); diff --git a/CPF/Drawing/DrawingContext.cs b/CPF/Drawing/DrawingContext.cs index adcba73..abd4098 100644 --- a/CPF/Drawing/DrawingContext.cs +++ b/CPF/Drawing/DrawingContext.cs @@ -243,6 +243,15 @@ namespace CPF.Drawing } } + /// + /// 重置画布 + /// + /// + public virtual bool ResetHdcCanvas(IRenderTarget renderTarget) + { + return false; + } + public abstract DrawingFactory DrawingFactory { get; } public static DrawingContext FromBitmap(Bitmap bmp)