mirror of
https://github.com/microsoft/terminal.git
synced 2025-12-10 00:48:23 -06:00
atlas,d2d: overdraw background bitmap by one cell on all sides (#17674)
BackendD2D will now draw one extra cell on all sides when rendering the background, filled with the expected background color, starting at (-1, -1) to ensure that cell backgrounds do not bleed over the edges of the viewport where the is swapchain but no content. Fixes #17672 (cherry picked from commit 9007fc2894f877175c63592ab1f7b3300a23abf8) Service-Card-Id: 93494324 Service-Version: 1.21
This commit is contained in:
parent
8f4775df96
commit
4040e4c654
@ -80,6 +80,7 @@ void BackendD2D::_handleSettingsUpdate(const RenderingPayload& p)
|
||||
const auto renderTargetChanged = !_renderTarget;
|
||||
const auto fontChanged = _fontGeneration != p.s->font.generation();
|
||||
const auto cursorChanged = _cursorGeneration != p.s->cursor.generation();
|
||||
const auto backgroundColorChanged = _miscGeneration != p.s->misc.generation();
|
||||
const auto cellCountChanged = _viewportCellCount != p.s->viewportCellCount;
|
||||
|
||||
if (renderTargetChanged)
|
||||
@ -125,7 +126,7 @@ void BackendD2D::_handleSettingsUpdate(const RenderingPayload& p)
|
||||
_builtinGlyphsRenderTargetActive = false;
|
||||
}
|
||||
|
||||
if (renderTargetChanged || fontChanged || cellCountChanged)
|
||||
if (renderTargetChanged || fontChanged || cellCountChanged || backgroundColorChanged)
|
||||
{
|
||||
const D2D1_BITMAP_PROPERTIES props{
|
||||
.pixelFormat = { DXGI_FORMAT_R8G8B8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED },
|
||||
@ -133,18 +134,40 @@ void BackendD2D::_handleSettingsUpdate(const RenderingPayload& p)
|
||||
.dpiY = static_cast<f32>(p.s->font->dpi),
|
||||
};
|
||||
const D2D1_SIZE_U size{
|
||||
p.s->viewportCellCount.x,
|
||||
p.s->viewportCellCount.y,
|
||||
p.s->viewportCellCount.x + 2u,
|
||||
p.s->viewportCellCount.y + 2u,
|
||||
};
|
||||
const D2D1_MATRIX_3X2_F transform{
|
||||
.m11 = static_cast<f32>(p.s->font->cellSize.x),
|
||||
.m22 = static_cast<f32>(p.s->font->cellSize.y),
|
||||
/* Brushes are transformed relative to the render target, not the rect into which they are painted. */
|
||||
.dx = -static_cast<f32>(p.s->font->cellSize.x),
|
||||
.dy = -static_cast<f32>(p.s->font->cellSize.y),
|
||||
};
|
||||
THROW_IF_FAILED(_renderTarget->CreateBitmap(size, nullptr, 0, &props, _backgroundBitmap.put()));
|
||||
|
||||
/*
|
||||
We're allocating a bitmap that is one pixel wider on every side than the viewport so that we can fill in the gutter
|
||||
with the background color. D2D doesn't have an equivalent to D3D11_TEXTURE_ADDRESS_BORDER, which we use in the D3D
|
||||
backend to ensure the colors don't bleed off the edges.
|
||||
|
||||
XXXXXXXXXXXXXXXX <- background color
|
||||
X+------------+X
|
||||
X| viewport |X
|
||||
X| |X
|
||||
X| |X
|
||||
X+------------+X
|
||||
XXXXXXXXXXXXXXXX
|
||||
|
||||
The translation in `transform` ensures that we render it off the top left of the render target.
|
||||
*/
|
||||
auto backgroundFill = std::make_unique_for_overwrite<u32[]>(static_cast<size_t>(size.width) * size.height);
|
||||
std::fill_n(backgroundFill.get(), size.width * size.height, u32ColorPremultiply(p.s->misc->backgroundColor));
|
||||
|
||||
THROW_IF_FAILED(_renderTarget->CreateBitmap(size, backgroundFill.get(), size.width * sizeof(u32), &props, _backgroundBitmap.put()));
|
||||
THROW_IF_FAILED(_renderTarget->CreateBitmapBrush(_backgroundBitmap.get(), _backgroundBrush.put()));
|
||||
_backgroundBrush->SetInterpolationMode(D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR);
|
||||
_backgroundBrush->SetExtendModeX(D2D1_EXTEND_MODE_MIRROR);
|
||||
_backgroundBrush->SetExtendModeY(D2D1_EXTEND_MODE_MIRROR);
|
||||
_backgroundBrush->SetExtendModeX(D2D1_EXTEND_MODE_CLAMP);
|
||||
_backgroundBrush->SetExtendModeY(D2D1_EXTEND_MODE_CLAMP);
|
||||
_backgroundBrush->SetTransform(&transform);
|
||||
_backgroundBitmapGeneration = {};
|
||||
}
|
||||
@ -158,6 +181,7 @@ void BackendD2D::_handleSettingsUpdate(const RenderingPayload& p)
|
||||
_generation = p.s.generation();
|
||||
_fontGeneration = p.s->font.generation();
|
||||
_cursorGeneration = p.s->cursor.generation();
|
||||
_miscGeneration = p.s->misc.generation();
|
||||
_viewportCellCount = p.s->viewportCellCount;
|
||||
}
|
||||
|
||||
@ -165,7 +189,13 @@ void BackendD2D::_drawBackground(const RenderingPayload& p)
|
||||
{
|
||||
if (_backgroundBitmapGeneration != p.colorBitmapGenerations[0])
|
||||
{
|
||||
THROW_IF_FAILED(_backgroundBitmap->CopyFromMemory(nullptr, p.backgroundBitmap.data(), gsl::narrow_cast<UINT32>(p.colorBitmapRowStride * sizeof(u32))));
|
||||
const D2D1_RECT_U rect{
|
||||
1u,
|
||||
1u,
|
||||
1u + p.s->viewportCellCount.x,
|
||||
1u + p.s->viewportCellCount.y,
|
||||
};
|
||||
THROW_IF_FAILED(_backgroundBitmap->CopyFromMemory(&rect, p.backgroundBitmap.data(), gsl::narrow_cast<UINT32>(p.colorBitmapRowStride * sizeof(u32))));
|
||||
_backgroundBitmapGeneration = p.colorBitmapGenerations[0];
|
||||
}
|
||||
|
||||
|
||||
@ -64,6 +64,7 @@ namespace Microsoft::Console::Render::Atlas
|
||||
til::generation_t _generation;
|
||||
til::generation_t _fontGeneration;
|
||||
til::generation_t _cursorGeneration;
|
||||
til::generation_t _miscGeneration;
|
||||
u16x2 _viewportCellCount{};
|
||||
|
||||
#if ATLAS_DEBUG_SHOW_DIRTY
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user