允许复用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); 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) //public SkiaDrawingContext(SKBitmap bitmap)
//{ //{
// this.bitmap = bitmap; // this.bitmap = bitmap;

View File

@ -939,6 +939,10 @@ namespace CPF.Windows
// gl.PopMatrix(); // gl.PopMatrix();
// gl.Flush(); // gl.Flush();
//} //}
IRenderTarget lastRenderTarget;
DrawingContext cacheDC;
void OnPaint(IntPtr hdc, Rect rect) void OnPaint(IntPtr hdc, Rect rect)
{ {
if (handle == IntPtr.Zero) if (handle == IntPtr.Zero)
@ -1013,10 +1017,26 @@ namespace CPF.Windows
wglContext.GetFramebufferInfo(out var fb, out var sam, out var sten); 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); 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); //DrawRenderRectangle(dc);
} }
//testPaint(); //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 abstract DrawingFactory DrawingFactory { get; }
public static DrawingContext FromBitmap(Bitmap bmp) public static DrawingContext FromBitmap(Bitmap bmp)