允许复用Context

在内存比较小的旧电脑上,在调用
var bitmap = new SKBitmap(BITMAP.bmWidth, BITMAP.bmHeight);时
会因为SKBitmap.TryAllocPixels 随机出现System.Exception: Unable to allocate pixels for the bitmap.   复用Context,减小SKBitmap.TryAllocPixels 调用
This commit is contained in:
新无止竞 2024-06-18 11:17:07 +08:00
parent 5f52372fb4
commit d32b6ef87f
3 changed files with 65 additions and 3 deletions

View File

@ -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<IntPtr> 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;

View File

@ -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<IntPtr>(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();

View File

@ -243,6 +243,15 @@ namespace CPF.Drawing
}
}
/// <summary>
/// 重置画布
/// </summary>
/// <param name="renderTarget"></param>
public virtual bool ResetHdcCanvas(IRenderTarget renderTarget)
{
return false;
}
public abstract DrawingFactory DrawingFactory { get; }
public static DrawingContext FromBitmap(Bitmap bmp)