2020-01-03 15:25:21 +01:00
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
# pragma once
Move ConPTY to use til::bitmap (#5024)
## 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
2020-03-23 16:57:54 +01:00
# define _TIL_INLINEPREFIX __declspec(noinline) inline
2020-01-20 21:53:24 +01:00
# include "til/at.h"
2020-03-10 01:17:24 +01:00
# include "til/color.h"
2020-03-27 23:48:49 +01:00
# include "til/math.h"
2020-01-09 18:07:52 +01:00
# include "til/some.h"
2020-03-10 21:51:26 +01:00
# include "til/size.h"
2020-03-13 01:04:43 +01:00
# include "til/point.h"
Move ConPTY to use til::bitmap (#5024)
## 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
2020-03-23 16:57:54 +01:00
# include "til/operators.h"
2020-04-13 22:09:02 +02:00
# include "til/rectangle.h"
2021-05-20 19:27:50 +02:00
# include "til/rle.h"
2020-03-19 17:10:13 +01:00
# include "til/bitmap.h"
2020-01-30 01:55:48 +01:00
# include "til/u8u16convert.h"
Added til::spsc, a lock-free, single-producer/-consumer FIFO queue (#6751)
## Summary of the Pull Request
This PR adds the `til::spsc` namespace, which implements a lock-free, single-producer, single-consumer FIFO queue ("channel"). The queue efficiently blocks the caller using Futexes if no data can be written to / read from the queue (e.g. using `WaitOnAddress` on Windows). Furthermore it allows batching of data and contains logic to signal the caller if the other side has been dropped/destructed.
## PR Checklist
* [ ] Closes #xxx
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [x] Tests added/passed
* [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx
* [ ] Schema updated.
* [x] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx
## Detailed Description of the Pull Request / Additional comments
`til::spsc::details::arc<T>` contains most of the queue's logic and as such has the relevant documentation for its design.
## Validation Steps Performed
The queue was tested on Windows, Linux and macOS using MSVC, gcc and llvm and each of their available runtime introspection utilities in order to ensure no race conditions or memory leaks occur.
2020-07-16 22:49:06 +02:00
# include "til/spsc.h"
2020-08-08 01:07:42 +02:00
# include "til/coalesce.h"
Add support for iterable, nested commands (#6856)
## Summary of the Pull Request
This PR adds support for both _nested_ and _iterable_ commands in the Command palette.
![nested-commands-000](https://user-images.githubusercontent.com/18356694/87072916-2d991c00-c1e2-11ea-8917-a70e8b8b9803.gif)
* **Nested commands**: These are commands that include additional sub-commands. When the user selects on of these, the palette will update to only show the nested commands.
* **Iterable commands**: These are commands what allow the user to define only a single command, which is repeated once for every profile. (in the future, also repeated for color schemes, themes, etc.)
The above gif uses the following json:
```json
{
"name": "Split Pane...",
"commands": [
{
"iterateOn": "profiles",
"name": "Split with ${profile.name}...",
"commands": [
{ "command": { "action": "splitPane", "profile": "${profile.name}", "split": "automatic" } },
{ "command": { "action": "splitPane", "profile": "${profile.name}", "split": "vertical" } },
{ "command": { "action": "splitPane", "profile": "${profile.name}", "split": "horizontal" } }
]
}
]
},
```
## References
## PR Checklist
* [x] Closes #3994
* [x] I work here
* [x] Tests added/passed
* [ ] Requires documentation to be updated - Sure does, but we'll finish polishing this first.
## Detailed Description of the Pull Request / Additional comments
We've now gotta keep the original json for a command around, so that once we know what all the profiles will be, we can expand the commands that need it.
We've also got to parse commands recursively, because they might have any number of child commands.
These together made the command parsing a _lot_ more complicated, but it feels good so far.
## Validation Steps Performed
* wrote a bunch of tests
* Played with it a bunch
2020-08-13 23:22:46 +02:00
# include "til/replace.h"
2021-06-11 01:24:21 +02:00
# include "til/string.h"
2021-01-22 05:57:26 +01:00
# include "til/pmr.h"
2020-01-09 18:07:52 +01:00
2021-05-15 01:14:26 +02:00
// Use keywords on TraceLogging providers to specify the category
// of event that we are emitting for filtering purposes.
// The bottom 48 bits (0..47) are definable by each provider.
// The top 16 bits are reserved by Microsoft.
// NOTE: Any provider registering TraceLoggingOptionMicrosoftTelemetry
// should also reserve bits 43..47 for telemetry controls.
//
// To ensure that providers that transmit both telemetry
// and diagnostic information do not do excess work when only
// a telemetry listener is attached, please set a keyword
// on all TraceLoggingWrite statements.
//
// Use TIL_KEYWORD_TRACE if you are basically
// using it as a printf-like debugging tool for super
// deep diagnostics reasons only.
//
// Please do NOT leave events marked without a keyword
// or filtering on intent will not be possible.
//
// See also https://osgwiki.com/wiki/TraceLogging#Semantics
//
// Note that Conhost had already defined some keywords
2021-05-24 23:24:01 +02:00
// between bits 0..12 so be sure to not overlap those.
2021-05-15 01:14:26 +02:00
// See `TraceKeywords`.
// We will therefore try to reserve 32..42 for TIL
// as common flags for the entire Terminal team projects.
# define TIL_KEYWORD_TRACE 0x0000000100000000 // bit 32
2020-01-03 15:25:21 +01:00
namespace til // Terminal Implementation Library. Also: "Today I Learned"
{
2020-06-11 00:02:05 +02:00
template < typename T >
void manage_vector ( std : : vector < T > & vector , typename std : : vector < T > : : size_type requestedSize , float shrinkThreshold )
{
const auto existingCapacity = vector . capacity ( ) ;
const auto requiredCapacity = requestedSize ;
// Check by integer first as float math is way more expensive.
if ( requiredCapacity < existingCapacity )
{
// Now check if it's even worth shrinking. We don't want to shrink by 1 at a time, so meet a threshold first.
if ( requiredCapacity < = gsl : : narrow_cast < size_t > ( ( static_cast < float > ( existingCapacity ) * shrinkThreshold ) ) )
{
// There's no real way to force a shrink, so make a new one.
vector = std : : vector < T > { } ;
}
}
// Reserve won't shrink on its own and won't grow if we have enough space.
vector . reserve ( requiredCapacity ) ;
}
2020-01-03 15:25:21 +01:00
}
// These sit outside the namespace because they sit outside for WIL too.
// Inspired from RETURN_IF_WIN32_BOOL_FALSE
// WIL doesn't include a RETURN_BOOL_IF_FALSE, and RETURN_IF_WIN32_BOOL_FALSE
// will actually return the value of GLE.
# define RETURN_BOOL_IF_FALSE(b) \
do \
{ \
const bool __boolRet = wil : : verify_bool ( b ) ; \
if ( ! __boolRet ) \
{ \
return __boolRet ; \
} \
} while ( 0 , 0 )
// Due to a bug (DevDiv 441931), Warning 4297 (function marked noexcept throws exception) is detected even when the throwing code is unreachable, such as the end of scope after a return, in function-level catch.
# define CATCH_LOG_RETURN_FALSE() \
catch ( . . . ) \
{ \
__pragma ( warning ( suppress : 4297 ) ) ; \
LOG_CAUGHT_EXCEPTION ( ) ; \
return false ; \
}
2020-02-10 23:09:08 +01:00
// MultiByteToWideChar has a bug in it where it can return 0 and then not set last error.
// WIL has a fit if the last error is 0 when a bool false is returned.
// This macro doesn't have a fit. It just reports E_UNEXPECTED instead.
# define THROW_LAST_ERROR_IF_AND_IGNORE_BAD_GLE(condition) \
do \
{ \
if ( condition ) \
{ \
const auto gle = : : GetLastError ( ) ; \
if ( gle ) \
{ \
THROW_WIN32 ( gle ) ; \
} \
else \
{ \
THROW_HR ( E_UNEXPECTED ) ; \
} \
} \
} while ( 0 , 0 )