Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove some allocations related to GudelineSet and DoubleCollection #10310

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -931,11 +931,10 @@ internal override void PushGuidelineY1(
// Convert compact record to generic GuidelineSet.
//

GuidelineSet guidelineCollection = new GuidelineSet(
null, // x guidelines
new double[] { coordinate, 0 }, // y guidelines
true // dynamic flag
);
GuidelineSet guidelineCollection = new(guidelinesX: ReadOnlySpan<double>.Empty,
guidelinesY: [coordinate, 0],
isDynamic: true);

guidelineCollection.Freeze();

//
Expand Down Expand Up @@ -977,15 +976,9 @@ internal override void PushGuidelineY2(
// Convert compact record to generic GuidelineSet.
//

GuidelineSet guidelineCollection = new GuidelineSet(
null, // x guidelines
new double[]
{
leadingCoordinate,
offsetToDrivenCoordinate
}, // y guidelines
true // dynamic flag
);
GuidelineSet guidelineCollection = new(guidelinesX: ReadOnlySpan<double>.Empty,
guidelinesY: [leadingCoordinate, offsetToDrivenCoordinate],
isDynamic: true);
guidelineCollection.Freeze();

//
Expand Down
h3xds1nz marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,20 @@ public DoubleCollection(int capacity)
_collection = new FrugalStructList<double>(capacity);
}

/// <summary>
/// Initializes a new instance using a <paramref name="values"/>. Elements are copied.
/// </summary>
/// <param name="values"></param>
internal DoubleCollection(params ReadOnlySpan<double> values)
{
_collection = new FrugalStructList<double>(values.Length);

foreach (double item in values)
{
_collection.Add(item);
}
}

/// <summary>
/// Creates a DoubleCollection with all of the same elements as collection
/// </summary>
Expand Down Expand Up @@ -934,12 +948,6 @@ public DoubleCollection(IEnumerable<double> collection)
}
}







WritePostscript();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,42 @@ public GuidelineSet()
/// <param name="guidelinesX">Array of X coordinates that defines a set of vertical guidelines.</param>
/// <param name="guidelinesY">Array of Y coordinates that defines a set of horizontal guidelines.</param>
/// <param name="isDynamic">Usage flag: when true then rendering machine will detect animation state and apply subpixel animation behavior.</param>
internal GuidelineSet(double[] guidelinesX, double[] guidelinesY, bool isDynamic)
internal GuidelineSet(ReadOnlySpan<double> guidelinesX, ReadOnlySpan<double> guidelinesY)
{
if (guidelinesX != null)
if (!guidelinesX.IsEmpty)
{
// Dynamic guideline is defined by a pair of numbers: (coordinate, shift),
// so the legnth of array should be even.
GuidelinesX = new DoubleCollection(guidelinesX);
}

if (!guidelinesY.IsEmpty)
{
GuidelinesY = new DoubleCollection(guidelinesY);
}
}

/// <summary>
/// Constructs a new GuidelineSet object.
/// This constructor is internal for now, till we'll find a solution
/// for multi-path dynamic guideline implementation. If/when it'll happen,
/// it should become "public" so that the next constructor (without "isDynamic'
/// argument) may go away.
/// </summary>
/// <param name="guidelinesX">Array of X coordinates that defines a set of vertical guidelines.</param>
/// <param name="guidelinesY">Array of Y coordinates that defines a set of horizontal guidelines.</param>
/// <param name="isDynamic">Usage flag: when true then rendering machine will detect animation state and apply subpixel animation behavior.</param>
internal GuidelineSet(ReadOnlySpan<double> guidelinesX, ReadOnlySpan<double> guidelinesY, bool isDynamic)
{
if (!guidelinesX.IsEmpty)
{
// Dynamic guideline is defined by a pair of numbers: (coordinate, shift), so the length of array should be even.
Debug.Assert(!isDynamic || guidelinesX.Length % 2 == 0);

GuidelinesX = new DoubleCollection(guidelinesX);
}

if (guidelinesY != null)
if (!guidelinesY.IsEmpty)
{
// Dynamic guideline is defined by a pair of numbers: (coordinate, shift),
// so the legnth of array should be even.
// Dynamic guideline is defined by a pair of numbers: (coordinate, shift), so the length of array should be even.
Debug.Assert(!isDynamic || guidelinesY.Length % 2 == 0);

GuidelinesY = new DoubleCollection(guidelinesY);
Expand All @@ -70,14 +91,14 @@ internal GuidelineSet(double[] guidelinesX, double[] guidelinesY, bool isDynamic
/// <param name="guidelinesY">Array of Y coordinates that defines a set of horizontal guidelines.</param>
public GuidelineSet(double[] guidelinesX, double[] guidelinesY)
{
if (guidelinesX != null)
if (guidelinesX is not null)
{
GuidelinesX = new DoubleCollection(guidelinesX);
GuidelinesX = new DoubleCollection(guidelinesX.AsSpan());
}

if (guidelinesY != null)
if (guidelinesY is not null)
{
GuidelinesY = new DoubleCollection(guidelinesY);
GuidelinesY = new DoubleCollection(guidelinesY.AsSpan());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -979,14 +979,13 @@ private void updatePixelSnappingGuidelines()
}
else
{
DoubleCollection xLines = this.VisualXSnappingGuidelines;
DoubleCollection xLines = VisualXSnappingGuidelines;

if(xLines == null)
if (xLines is null)
{
xLines = new DoubleCollection();
xLines.Add(0d);
xLines.Add(this.RenderSize.Width);
this.VisualXSnappingGuidelines = xLines;
xLines = new DoubleCollection(0d, RenderSize.Width);

VisualXSnappingGuidelines = xLines;
}
else
{
Expand All @@ -997,13 +996,12 @@ private void updatePixelSnappingGuidelines()
xLines[lastGuideline] = this.RenderSize.Width;
}

DoubleCollection yLines = this.VisualYSnappingGuidelines;
if(yLines == null)
DoubleCollection yLines = VisualYSnappingGuidelines;
if (yLines is null)
{
yLines = new DoubleCollection();
yLines.Add(0d);
yLines.Add(this.RenderSize.Height);
this.VisualYSnappingGuidelines = yLines;
yLines = new DoubleCollection(0d, RenderSize.Height);

VisualYSnappingGuidelines = yLines;
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ internal InkCanvasFeedbackAdorner(InkCanvas inkCanvas)
// Initialize the internal data
_inkCanvas = inkCanvas;

_adornerBorderPen = new Pen(Brushes.Black, 1.0);
DoubleCollection dashes = new DoubleCollection();
dashes.Add(4.5);
dashes.Add(4.5);
_adornerBorderPen.DashStyle = new DashStyle(dashes, 2.25);
_adornerBorderPen.DashCap = PenLineCap.Flat;
_adornerBorderPen = new Pen(Brushes.Black, 1.0)
{
DashStyle = new DashStyle(new DoubleCollection(4.5, 4.5), 2.25),
DashCap = PenLineCap.Flat
};
_adornerBorderPen.Freeze();
}

/// <summary>
Expand Down Expand Up @@ -167,7 +167,7 @@ internal void UpdateBounds(Rect rect)
private double _offsetX = 0;
private double _offsetY = 0;

private Pen _adornerBorderPen;
private readonly Pen _adornerBorderPen;

private const int CornerResizeHandleSize = 8;
private const double BorderMargin = 8f;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,11 @@ internal InkCanvasSelectionAdorner(UIElement adornedElement)
"InkCanvasSelectionAdorner only should be used by InkCanvas internally");

// Initialize the internal data.
_adornerBorderPen = new Pen(Brushes.Black, 1.0);
DoubleCollection dashes = new DoubleCollection();
dashes.Add(4.5);
dashes.Add(4.5);
_adornerBorderPen.DashStyle = new DashStyle(dashes, 2.25);
_adornerBorderPen.DashCap = PenLineCap.Flat;
_adornerBorderPen = new Pen(Brushes.Black, 1.0)
{
DashStyle = new DashStyle(new DoubleCollection(4.5, 4.5), 2.25),
DashCap = PenLineCap.Flat
};
_adornerBorderPen.Freeze();

_adornerPenBrush = new Pen(new SolidColorBrush(Color.FromRgb(132, 146, 222)), 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3963,20 +3963,20 @@ internal class GridLinesRenderer : DrawingVisual
/// </summary>
static GridLinesRenderer()
{
s_oddDashPen = new Pen(Brushes.Blue, c_penWidth);
DoubleCollection oddDashArray = new DoubleCollection();
oddDashArray.Add(c_dashLength);
oddDashArray.Add(c_dashLength);
s_oddDashPen.DashStyle = new DashStyle(oddDashArray, 0);
s_oddDashPen.DashCap = PenLineCap.Flat;
DoubleCollection dashArray = new DoubleCollection(DashLength, DashLength);

s_oddDashPen = new Pen(Brushes.Blue, PenWidth)
{
DashStyle = new DashStyle(dashArray, 0),
DashCap = PenLineCap.Flat
};
s_oddDashPen.Freeze();

s_evenDashPen = new Pen(Brushes.Yellow, c_penWidth);
DoubleCollection evenDashArray = new DoubleCollection();
evenDashArray.Add(c_dashLength);
evenDashArray.Add(c_dashLength);
s_evenDashPen.DashStyle = new DashStyle(evenDashArray, c_dashLength);
s_evenDashPen.DashCap = PenLineCap.Flat;
s_evenDashPen = new Pen(Brushes.Yellow, PenWidth)
{
DashStyle = new DashStyle(dashArray, DashLength),
DashCap = PenLineCap.Flat
};
s_evenDashPen.Freeze();
}

Expand Down Expand Up @@ -4029,11 +4029,10 @@ private static void DrawGridLine(
drawingContext.DrawLine(s_evenDashPen, start, end);
}

private const double c_dashLength = 4.0; //
private const double c_penWidth = 1.0; //
private const double DashLength = 4.0; //
private const double PenWidth = 1.0; //
private static readonly Pen s_oddDashPen; // first pen to draw dash
private static readonly Pen s_evenDashPen; // second pen to draw dash
private static readonly Point c_zeroPoint = new Point(0, 0);
}

#endregion Private Structures Classes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -430,11 +430,11 @@ protected override void OnRender(DrawingContext dc)
Pen pen = new Pen(Fill, 1.0d);

bool snapsToDevicePixels = SnapsToDevicePixels;
DoubleCollection xLines = snapsToDevicePixels ? new DoubleCollection() : null;
DoubleCollection yLines = snapsToDevicePixels ? new DoubleCollection() : null;
DoubleCollection xLines = snapsToDevicePixels ? new DoubleCollection(4) : null;
DoubleCollection yLines = snapsToDevicePixels ? new DoubleCollection(6) : null;
h3xds1nz marked this conversation as resolved.
Show resolved Hide resolved

// Is it Vertical?
if ((Placement == TickBarPlacement.Left) || (Placement == TickBarPlacement.Right))
if (Placement is TickBarPlacement.Left or TickBarPlacement.Right)
{
// Reduce tick interval if it is more than would be visible on the screen
double interval = TickFrequency;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,9 @@ internal void OnRenderCaretSubElement(DrawingContext context)
// Snap the caret to device pixels.
if (!_italic || threadLocalStore.Bidi)
{
GuidelineSet guidelineSet = new GuidelineSet(new double[] { -(_systemCaretWidth / 2), _systemCaretWidth / 2 }, null);
GuidelineSet guidelineSet = new(guidelinesX: [-(_systemCaretWidth / 2), _systemCaretWidth / 2],
guidelinesY: ReadOnlySpan<double>.Empty);

context.PushGuidelineSet(guidelineSet);
contextPushedCount++;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,6 @@ protected override void OnRender(DrawingContext drawingContext)
// Render the each of the composition string attribute from the attribute ranges.
for (int i = 0; i < _attributeRanges.Count; i++)
{
DoubleCollection dashArray;

// Get the composition attribute range from the attribute range lists
AttributeRange attributeRange = (AttributeRange)_attributeRanges[i];

Expand Down Expand Up @@ -186,14 +184,10 @@ protected override void OnRender(DrawingContext drawingContext)
{
case UnsafeNativeMethods.TF_DA_LINESTYLE.TF_LS_DOT:
// Add the dot length and specify the start/end line cap as the round
dashArray = new DoubleCollection();
dashArray.Add(DotLength);
dashArray.Add(DotLength);

pen.DashStyle = new DashStyle(dashArray, 0);
pen.DashCap = System.Windows.Media.PenLineCap.Round;
pen.StartLineCap = System.Windows.Media.PenLineCap.Round;
pen.EndLineCap = System.Windows.Media.PenLineCap.Round;
pen.DashStyle = new DashStyle(new DoubleCollection(DotLength, DotLength), 0);
pen.DashCap = PenLineCap.Round;
pen.StartLineCap = PenLineCap.Round;
pen.EndLineCap = PenLineCap.Round;

// Update the line height for the dot line. Dot line will be more thickness than
// other line to show it clearly.
Expand All @@ -205,21 +199,17 @@ protected override void OnRender(DrawingContext drawingContext)
double dashLength = height * (lineBold ? BoldDashRatio : NormalDashRatio);
double dashGapLength = height * (lineBold ? BoldDashGapRatio : NormalDashGapRatio);

// Add the dash and dash gap legth
dashArray = new DoubleCollection();
dashArray.Add(dashLength);
dashArray.Add(dashGapLength);

pen.DashStyle = new DashStyle(dashArray, 0);
pen.DashCap = System.Windows.Media.PenLineCap.Round;
pen.StartLineCap = System.Windows.Media.PenLineCap.Round;
pen.EndLineCap = System.Windows.Media.PenLineCap.Round;
// Add the dash and dash gap length
pen.DashStyle = new DashStyle(new DoubleCollection(dashLength, dashGapLength), 0);
pen.DashCap = PenLineCap.Round;
pen.StartLineCap = PenLineCap.Round;
pen.EndLineCap = PenLineCap.Round;

break;

case UnsafeNativeMethods.TF_DA_LINESTYLE.TF_LS_SOLID:
pen.StartLineCap = System.Windows.Media.PenLineCap.Round;
pen.EndLineCap = System.Windows.Media.PenLineCap.Round;
pen.StartLineCap = PenLineCap.Round;
pen.EndLineCap = PenLineCap.Round;

break;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -560,10 +560,10 @@ protected int PushAll(DrawingContext dc)
{
Rect bounds = GetRectBounds(true);

double[] snapx = new double[] { bounds.Left, bounds.Right };
double[] snapy = new double[] { bounds.Top, bounds.Bottom };
ReadOnlySpan<double> snapX = [bounds.Left, bounds.Right];
ReadOnlySpan<double> snapY = [bounds.Top, bounds.Bottom];

dc.PushGuidelineSet(new GuidelineSet(snapx, snapy));
dc.PushGuidelineSet(new GuidelineSet(snapX, snapY));
level++;
}

Expand Down