This PR fixes #2338 and implements basic damage rectangle optimization leveraging the fact that pixman does a pretty good chunk of the work already. This is a somewhat naive implementation that could theoretically be more fine-tuned and optimized with custom data structures, but honestly, it's good enough for any practical purposes. Heck, even not doing any additional optimization was already good enough for practical purposes.
The algorithm used here is quite simple: it just collects all the damage for each row, consolidates the row's damage into some number of rectangles (to reduce the number of small "bad" rectangles
that would otherwise cause frequent and bad merges) and then adds the new rectangle to the worker's damage region. If the number of rectangles in the damage buffer exceeds some per-worker limit, then it merges each rectangle in the worker damage buffer with its neighbor.
As a bonus, benchmarks on my machine show substantial improvements for most of vtebench's scrolling benchmarks at high numbers of lines/cols and minimal effect on small resolutions.