Skip to content

Commit

Permalink
ImageSurface: Support memory pressure
Browse files Browse the repository at this point in the history
  • Loading branch information
badcel committed Aug 28, 2024
1 parent 3f6a62b commit 6e10363
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 5 deletions.
23 changes: 22 additions & 1 deletion src/Libs/cairo-1.0/Internal/SurfaceHandle.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
namespace Cairo.Internal;
using System;

namespace Cairo.Internal;

public partial class SurfaceOwnedHandle
{
private long _memoryPressure;

Check warning on line 8 in src/Libs/cairo-1.0/Internal/SurfaceHandle.cs

View workflow job for this annotation

GitHub Actions / Build (Linux)

Fix formatting

Check warning on line 8 in src/Libs/cairo-1.0/Internal/SurfaceHandle.cs

View workflow job for this annotation

GitHub Actions / Build (Linux)

Fix formatting
internal void AddMemoryPressure(long memoryPressure)
{
if (memoryPressure > 0)
{
_memoryPressure = memoryPressure;
GC.AddMemoryPressure(_memoryPressure);

Check warning on line 14 in src/Libs/cairo-1.0/Internal/SurfaceHandle.cs

View workflow job for this annotation

GitHub Actions / Build (Linux)

Fix formatting

Check warning on line 14 in src/Libs/cairo-1.0/Internal/SurfaceHandle.cs

View workflow job for this annotation

GitHub Actions / Build (Linux)

Fix formatting
}
}

private void RemoveMemoryPressure()
{
if(_memoryPressure > 0)

Check warning on line 20 in src/Libs/cairo-1.0/Internal/SurfaceHandle.cs

View workflow job for this annotation

GitHub Actions / Build (Linux)

Fix formatting

Check warning on line 20 in src/Libs/cairo-1.0/Internal/SurfaceHandle.cs

View workflow job for this annotation

GitHub Actions / Build (Linux)

Fix formatting
GC.RemoveMemoryPressure(_memoryPressure);
}

Check warning on line 23 in src/Libs/cairo-1.0/Internal/SurfaceHandle.cs

View workflow job for this annotation

GitHub Actions / Build (Linux)

Fix formatting

Check warning on line 23 in src/Libs/cairo-1.0/Internal/SurfaceHandle.cs

View workflow job for this annotation

GitHub Actions / Build (Linux)

Fix formatting
protected override bool ReleaseHandle()
{
RemoveMemoryPressure();

Surface.Destroy(handle);
return true;
}
Expand Down
13 changes: 10 additions & 3 deletions src/Libs/cairo-1.0/Public/ImageSurface.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,27 @@ public class ImageSurface : Surface
public ImageSurface(Format format, int width, int height)
: base(Internal.ImageSurface.Create(format, width, height))
{
Handle.AddMemoryPressure(GetSizeInBytes());
}

public Format Format => Internal.ImageSurface.GetFormat(Handle);
public int Height => Internal.ImageSurface.GetHeight(Handle);
public int Width => Internal.ImageSurface.GetWidth(Handle);

Check warning on line 16 in src/Libs/cairo-1.0/Public/ImageSurface.cs

View workflow job for this annotation

GitHub Actions / Build (Linux)

Fix formatting

Check warning on line 16 in src/Libs/cairo-1.0/Public/ImageSurface.cs

View workflow job for this annotation

GitHub Actions / Build (Linux)

Fix formatting
/// <summary>
/// Number of bytes per row.
/// </summary>
public int Stride => Internal.ImageSurface.GetStride(Handle);

private int GetSizeInBytes() => Stride * Height;

public Span<byte> GetData()
{
IntPtr data = Internal.ImageSurface.GetData(Handle);
int len = Stride * Height; // Stride is the number of bytes per row.
var data = Internal.ImageSurface.GetData(Handle);

unsafe
{
return new Span<byte>(data.ToPointer(), len);
return new Span<byte>(data.ToPointer(), GetSizeInBytes());
}
}
}
Expand Down
19 changes: 18 additions & 1 deletion src/Libs/cairo-1.0/Public/Surface.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,24 @@ public Surface CreateSimilar(Content content, int width, int height)
=> new Surface(Internal.Surface.CreateSimilar(Handle, content, width, height));

public Surface CreateSimilarImage(Format format, int width, int height)
=> new Surface(Internal.Surface.CreateSimilarImage(Handle, format, width, height));
{
var handle = Internal.Surface.CreateSimilarImage(Handle, format, width, height);

//See: https://www.cairographics.org/manual/cairo-Image-Surfaces.html#cairo-format-t
var bytesPerPixel = format switch
{
Format.A1 => 1 / 8d,
Format.A8 => 1,
Format.Argb32 => 4,
Format.Rgb24 => 4,
Format.Rgb30 => 4,
Format.Rgb16565 => 2,
_ => 0 //No memory pressure is applied
};
handle.AddMemoryPressure((long) (width * height * bytesPerPixel));

return new Surface(handle);
}

public Surface CreateForRectangle(double x, double y, double width, double height)
=> new Surface(Internal.Surface.CreateForRectangle(Handle, x, y, width, height));
Expand Down

0 comments on commit 6e10363

Please sign in to comment.