## Summary of the Pull Request Moves the ConPTY drawing mechanism (`VtRenderer`) to use the fine-grained `til::bitmap` individual-dirty-bit tracking mechanism instead of coarse-grained rectangle unions to improve drawing performance by dramatically reducing the total area redrawn. ## PR Checklist * [x] Part of #778 and #1064 * [x] I work here * [x] Tests added and updated. * [x] I'm a core contributor ## Detailed Description of the Pull Request / Additional comments - Converted `GetDirtyArea()` interface from `IRenderEngine` to use a vector of `til::rectangle` instead of the `SMALL_RECT` to banhammer inclusive rectangles. - `VtEngine` now holds and operates on the `til::bitmap` for invalidation regions. All invalidation operation functions that used to be embedded inside `VtEngine` are deleted in favor of using the ones in `til::bitmap`. - Updated `VtEngine` tracing to use new `til::bitmap` on trace and the new `to_string()` methods detailed below. - Comparison operators for `til::bitmap` and complementary tests. - Fixed an issue where the dirty rectangle shortcut in `til::bitmap` was set to 0,0,0,0 by default which means that `|=` on it with each `set()` operation was stretching the rectangle from 0,0. Now it's a `std::optional` so it has no value after just being cleared and will build from whatever the first invalidated rectangle is. Complementary tests added. - Optional run caching for `til::bitmap` in the `runs()` method since both VT and DX renderers will likely want to generate the set of runs at the beginning of a frame and refer to them over and over through that frame. Saves the iteration and creation and caches inside `til::bitmap` where the chance of invalidation of the underlying data is known best. It is still possible to iterate manually with `begin()` and `end()` from the outside without caching, if desired. Complementary tests added. - WEX templates added for `til::bitmap` and used in tests. - `translate()` method for `til::bitmap` which will slide the dirty points in the direction specified by a `til::point` and optionally back-fill the uncovered area as dirty. Complementary tests added. - Moves all string generation for `til` types `size`, `point`, `rectangle`, and `some` into a `to_string` method on each object such that it can be used in both ETW tracing scenarios AND in the TAEF templates uniformly. Adds a similar method for `bitmap`. - Add tagging to `_bitmap_const_iterator` such that it appears as a valid **Input Iterator** to STL collections and can be used in a `std::vector` constructor as a range. Adds and cleans up operators on this iterator to match the theoretical requirements for an **Input Iterator**. Complementary tests added. - Add loose operators to `til` which will allow some basic math operations (+, -, *, /) between `til::size` and `til::point` and vice versa. Complementary tests added. Complementary tests added. - Adds operators to `til::rectangle` to allow scaling with basic math operations (+, -, *) versus `til::size` and translation with basic math operations (+, -) against `til::point`. Complementary tests added. - In-place variants of some operations added to assorted `til` objects. Complementary tests added. - Update VT tests to compare invalidation against the new map structure instead of raw rectangles where possible. ## Validation Steps Performed - Wrote additional til Unit Tests for all additional operators and functions added to the project to support this operation - Updated the existing VT renderer tests - Ran perf check
130 lines
5.8 KiB
C++
130 lines
5.8 KiB
C++
/*++
|
|
Copyright (c) Microsoft Corporation
|
|
Licensed under the MIT license.
|
|
|
|
Module Name:
|
|
- IRenderEngine.hpp
|
|
|
|
Abstract:
|
|
- This serves as the entry point for a specific graphics engine specific renderer.
|
|
|
|
Author(s):
|
|
- Michael Niksa (MiNiksa) 17-Nov-2015
|
|
--*/
|
|
|
|
#pragma once
|
|
|
|
#include "../../inc/conattrs.hpp"
|
|
#include "Cluster.hpp"
|
|
#include "FontInfoDesired.hpp"
|
|
|
|
namespace Microsoft::Console::Render
|
|
{
|
|
class IRenderEngine
|
|
{
|
|
public:
|
|
enum GridLines
|
|
{
|
|
None = 0x0,
|
|
Top = 0x1,
|
|
Bottom = 0x2,
|
|
Left = 0x4,
|
|
Right = 0x8
|
|
};
|
|
|
|
struct CursorOptions
|
|
{
|
|
// Character cell in the grid to draw at
|
|
// This is relative to the viewport, not the buffer.
|
|
COORD coordCursor;
|
|
|
|
// For an underscore type _ cursor, how tall it should be as a % of cell height
|
|
ULONG ulCursorHeightPercent;
|
|
|
|
// For a vertical bar type | cursor, how many pixels wide it should be per ease of access preferences
|
|
ULONG cursorPixelWidth;
|
|
|
|
// Whether to draw the cursor 2 cells wide (+X from the coordinate given)
|
|
bool fIsDoubleWidth;
|
|
|
|
// Chooses a special cursor type like a full box, a vertical bar, etc.
|
|
CursorType cursorType;
|
|
|
|
// Specifies to use the color below instead of the default color
|
|
bool fUseColor;
|
|
|
|
// Color to use for drawing instead of the default
|
|
COLORREF cursorColor;
|
|
|
|
// Is the cursor currently visually visible?
|
|
// If the cursor has blinked off, this is false.
|
|
// if the cursor has blinked on, this is true.
|
|
bool isOn;
|
|
};
|
|
|
|
virtual ~IRenderEngine() = 0;
|
|
|
|
protected:
|
|
IRenderEngine() = default;
|
|
IRenderEngine(const IRenderEngine&) = default;
|
|
IRenderEngine(IRenderEngine&&) = default;
|
|
IRenderEngine& operator=(const IRenderEngine&) = default;
|
|
IRenderEngine& operator=(IRenderEngine&&) = default;
|
|
|
|
public:
|
|
[[nodiscard]] virtual HRESULT StartPaint() noexcept = 0;
|
|
[[nodiscard]] virtual HRESULT EndPaint() noexcept = 0;
|
|
[[nodiscard]] virtual HRESULT Present() noexcept = 0;
|
|
|
|
[[nodiscard]] virtual HRESULT PrepareForTeardown(_Out_ bool* const pForcePaint) noexcept = 0;
|
|
|
|
[[nodiscard]] virtual HRESULT ScrollFrame() noexcept = 0;
|
|
|
|
[[nodiscard]] virtual HRESULT Invalidate(const SMALL_RECT* const psrRegion) noexcept = 0;
|
|
[[nodiscard]] virtual HRESULT InvalidateCursor(const COORD* const pcoordCursor) noexcept = 0;
|
|
[[nodiscard]] virtual HRESULT InvalidateSystem(const RECT* const prcDirtyClient) noexcept = 0;
|
|
[[nodiscard]] virtual HRESULT InvalidateSelection(const std::vector<SMALL_RECT>& rectangles) noexcept = 0;
|
|
[[nodiscard]] virtual HRESULT InvalidateScroll(const COORD* const pcoordDelta) noexcept = 0;
|
|
[[nodiscard]] virtual HRESULT InvalidateAll() noexcept = 0;
|
|
[[nodiscard]] virtual HRESULT InvalidateCircling(_Out_ bool* const pForcePaint) noexcept = 0;
|
|
|
|
[[nodiscard]] virtual HRESULT InvalidateTitle(const std::wstring& proposedTitle) noexcept = 0;
|
|
|
|
[[nodiscard]] virtual HRESULT PaintBackground() noexcept = 0;
|
|
[[nodiscard]] virtual HRESULT PaintBufferLine(std::basic_string_view<Cluster> const clusters,
|
|
const COORD coord,
|
|
const bool fTrimLeft,
|
|
const bool lineWrapped) noexcept = 0;
|
|
[[nodiscard]] virtual HRESULT PaintBufferGridLines(const GridLines lines,
|
|
const COLORREF color,
|
|
const size_t cchLine,
|
|
const COORD coordTarget) noexcept = 0;
|
|
[[nodiscard]] virtual HRESULT PaintSelection(const SMALL_RECT rect) noexcept = 0;
|
|
|
|
[[nodiscard]] virtual HRESULT PaintCursor(const CursorOptions& options) noexcept = 0;
|
|
|
|
[[nodiscard]] virtual HRESULT UpdateDrawingBrushes(const COLORREF colorForeground,
|
|
const COLORREF colorBackground,
|
|
const WORD legacyColorAttribute,
|
|
const ExtendedAttributes extendedAttrs,
|
|
const bool isSettingDefaultBrushes) noexcept = 0;
|
|
[[nodiscard]] virtual HRESULT UpdateFont(const FontInfoDesired& FontInfoDesired,
|
|
_Out_ FontInfo& FontInfo) noexcept = 0;
|
|
[[nodiscard]] virtual HRESULT UpdateDpi(const int iDpi) noexcept = 0;
|
|
[[nodiscard]] virtual HRESULT UpdateViewport(const SMALL_RECT srNewViewport) noexcept = 0;
|
|
|
|
[[nodiscard]] virtual HRESULT GetProposedFont(const FontInfoDesired& FontInfoDesired,
|
|
_Out_ FontInfo& FontInfo,
|
|
const int iDpi) noexcept = 0;
|
|
|
|
virtual std::vector<til::rectangle> GetDirtyArea() = 0;
|
|
[[nodiscard]] virtual HRESULT GetFontSize(_Out_ COORD* const pFontSize) noexcept = 0;
|
|
[[nodiscard]] virtual HRESULT IsGlyphWideByFont(const std::wstring_view glyph, _Out_ bool* const pResult) noexcept = 0;
|
|
[[nodiscard]] virtual HRESULT UpdateTitle(const std::wstring& newTitle) noexcept = 0;
|
|
};
|
|
|
|
inline Microsoft::Console::Render::IRenderEngine::~IRenderEngine() {}
|
|
}
|
|
|
|
DEFINE_ENUM_FLAG_OPERATORS(Microsoft::Console::Render::IRenderEngine::GridLines)
|