From 95a8048282609c534cb1237b62415c2f01a2af11 Mon Sep 17 00:00:00 2001 From: Greg Depoire--Ferrer Date: Sat, 13 Jun 2020 20:11:22 +0200 Subject: [PATCH 1/3] Add fast path to til::bitmap::translate using bit shifts --- src/inc/til/bitmap.h | 56 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/inc/til/bitmap.h b/src/inc/til/bitmap.h index 3cb88830a54..ddc072d0361 100644 --- a/src/inc/til/bitmap.h +++ b/src/inc/til/bitmap.h @@ -194,6 +194,13 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned" // optional fill the uncovered area with bits. void translate(const til::point delta, bool fill = false) { + if (delta.x() == 0) + { + // fast path by using bit shifting + translate_y(delta.y(), fill); + return; + } + // FUTURE: PERF: GH #4015: This could use in-place walk semantics instead of a temporary. til::bitmap other{ _sz }; @@ -382,6 +389,55 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned" } private: + void translate_y(ptrdiff_t delta_y, bool fill) + { + if (delta_y == 0) + { + return; + } + + const auto bitShift = delta_y * _sz.width(); + + const auto newBits = static_cast(std::abs(bitShift)); + const bool isLeftShift = bitShift > 0; + + if (newBits >= _bits.size()) + { + if (fill) + { + set_all(); + } + else + { + reset_all(); + } + return; + } + + if (isLeftShift) + { + // This operator doesn't modify the size of `_bits`: the + // new bits are set to 0. + _bits <<= newBits; + } + else + { + _bits >>= newBits; + } + + if (fill) + { + if (isLeftShift) + { + _bits.set(0, newBits, true); + } + else + { + _bits.set(_bits.size() - newBits, newBits, true); + } + } + } + til::size _sz; til::rectangle _rc; dynamic_bitset<> _bits; From 37f33f66ccdea54948f15701825faf9576472cca Mon Sep 17 00:00:00 2001 From: Greg Depoire--Ferrer Date: Sat, 13 Jun 2020 20:45:29 +0200 Subject: [PATCH 2/3] fix Static Analysis --- src/inc/til/bitmap.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/inc/til/bitmap.h b/src/inc/til/bitmap.h index ddc072d0361..752c998c463 100644 --- a/src/inc/til/bitmap.h +++ b/src/inc/til/bitmap.h @@ -398,7 +398,11 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned" const auto bitShift = delta_y * _sz.width(); +#pragma warning(push) + // we can't depend on GSL here (some libraries use BLOCK_GSL), so we use static_cast for explicit narrowing +#pragma warning(disable : 26472) const auto newBits = static_cast(std::abs(bitShift)); +#pragma warning(pop) const bool isLeftShift = bitShift > 0; if (newBits >= _bits.size()) From 1e1491c921c3fe4680ca51f4ebefad0422b85226 Mon Sep 17 00:00:00 2001 From: Greg Depoire--Ferrer Date: Sun, 14 Jun 2020 09:03:47 +0200 Subject: [PATCH 3/3] Add _runs.reset() in translate_y --- src/inc/til/bitmap.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/inc/til/bitmap.h b/src/inc/til/bitmap.h index 752c998c463..d1f5dff7fd1 100644 --- a/src/inc/til/bitmap.h +++ b/src/inc/til/bitmap.h @@ -440,6 +440,8 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned" _bits.set(_bits.size() - newBits, newBits, true); } } + + _runs.reset(); // reset cached runs on any non-const method } til::size _sz;