Skip to content

API Proposal: More performant overloads for Graphics.GetContextInfo #47880

Closed
@JeremyKuhne

Description

@JeremyKuhne

Background and Motivation

Graphics.GetContextInfo exists to allow WinForms to apply cumulative Graphics transform translation and clipping to the underlying HDC so that rendering via GDI has similar output. This method currently returns an object array of [ Region, Matrix ]. (Note that the Matrix is the current Transform with only the cumulative offset applied.)

This API is called many times during rendering of WinForms applications. Avoiding the array allocation would make a significant difference in rendering allocations. A much greater allocation reduction would be obtained if Graphics tracked if the .Clip and .Transform setters are ever accessed to allow an early out in the method logic.

WinForms also don't always need both values. System.Drawing can't calculate the clipping region without the offset, but it can calculate the offset without the Region. Making the Region optional will save significant overhead.

In .NET 5.0 we added a lot of logic to WinForms to try and track and avoid getting this data. Tracking the "dirty" state in System.Drawing covers far more scenarios and allows significantly simpler code in WinForms.

Proposed API

namespace System.Drawing
{
    public sealed class Graphics
    {
         public object GetContextInfo();
+        public void GetContextInfo(out PointF offset);
+        public void GetContextInfo(out PointF offset, out Region clip);
    }
}
  • out Region clip would return null when Clip and Transform have never been set.
  • out Region clip would return null if the cumulative region ends up .IsInfinite() (meaningless)
  • out Point offset will return an empty (default) PointF when Transform has never been set.
  • existing GetContextInfo behavior won't change for compat

Usage Examples

The existing method is used in WinForms here.

Risks

If we missed a case where early out is inappropriate we'd have to adjust for that, but that is an internal detail.

More Details

  • GDI+ "layers" its clip and transform on top of the underlying GDI HDC. So a newly created Graphics object always has an infinite clip and identity matrix.
  • Restriction to translation in the Matrix is probably due to lack of Win9x support for rotation (not positive).

cc: @RussKie @merriemcgaw

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions