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)