mirror of
https://github.com/microsoft/terminal.git
synced 2026-04-14 18:21:02 +00:00
Compare commits
1 Commits
msbuildcac
...
dev/lhecke
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
69112b228f |
@@ -52,4 +52,103 @@ namespace til
|
||||
target = { target.data() + targetCount, target.size() - targetCount };
|
||||
source = { source.data() + sourceCount, source.size() - sourceCount };
|
||||
}
|
||||
|
||||
// memmove(), but you can specify a stride! This can be useful for copying between bitmaps.
|
||||
// A stride is (usually) the number of bytes between two rows in a bitmap. The stride doesn't necessarily
|
||||
// equal the actual number of pixels between rows, for instance for memory alignment purposes.
|
||||
//
|
||||
// All sizes are in bytes.
|
||||
//
|
||||
// Higher abstractions could be built on top of this function.
|
||||
void bytes_strided_copy(void* target, size_t targetStride, size_t targetSize, const void* source, size_t sourceStride, size_t sourceSize) noexcept
|
||||
{
|
||||
// Strides are supposed to be smaller than the whole bitmap size and the remaining code assumes that too.
|
||||
targetStride = std::min(targetStride, targetSize);
|
||||
sourceStride = std::min(sourceStride, sourceSize);
|
||||
|
||||
auto targetPtr = static_cast<uint8_t*>(target);
|
||||
auto sourcePtr = static_cast<const uint8_t*>(source);
|
||||
|
||||
// If the two bitmaps have the same stride we can just copy them in one go.
|
||||
if (sourceStride == targetStride)
|
||||
{
|
||||
memmove(targetPtr, sourcePtr, std::min(targetSize, sourceSize));
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto targetEnd = targetPtr + targetSize;
|
||||
const auto sourceEnd = sourcePtr + sourceSize;
|
||||
// The max. amount we can copy per row is the min. width (the intersection).
|
||||
const auto width = std::min(targetStride, sourceStride);
|
||||
|
||||
while (targetPtr < targetEnd && sourcePtr < sourceEnd)
|
||||
{
|
||||
memmove(targetPtr, sourcePtr, width);
|
||||
targetPtr += targetStride;
|
||||
sourcePtr += sourceStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fills the given rectangle inside target with the given value.
|
||||
// All values are in units of T, not in bytes.
|
||||
template<TriviallyCopyable T>
|
||||
void rect_fill(T* target, size_t targetStride, size_t targetSize, T value, size_t left, size_t top, size_t right, size_t bottom) noexcept
|
||||
{
|
||||
// Strides are supposed to be smaller than the whole bitmap size and the remaining code assumes that too.
|
||||
targetStride = std::min(targetStride, targetSize);
|
||||
|
||||
// Ensure that the rectangle is valid (left <= right && top <= bottom)
|
||||
// and within bounds (right <= width && bottom <= height).
|
||||
right = std::min(right, targetStride);
|
||||
left = std::min(left, right);
|
||||
bottom = std::min(bottom, targetSize / targetStride);
|
||||
top = std::min(top, bottom);
|
||||
|
||||
const auto height = bottom - top;
|
||||
const auto width = right - left;
|
||||
const auto offsetBeg = top * targetStride + left;
|
||||
const auto offsetEnd = bottom * targetStride + right;
|
||||
|
||||
const auto targetEnd = target + offsetEnd;
|
||||
target = target + offsetBeg;
|
||||
|
||||
// If we're allowed to fill entire rows at a time, we don't need to loop around the memset().
|
||||
if (width == targetStride)
|
||||
{
|
||||
if constexpr (sizeof(T) == 1)
|
||||
{
|
||||
// Memset is generally expected to be the fasted way to clear memory.
|
||||
memset(target, static_cast<unsigned char>(value), static_cast<size_t>(targetEnd - target));
|
||||
}
|
||||
else
|
||||
{
|
||||
// This should ideally compile down to a `rep stosb` or similar.
|
||||
for (; target < targetEnd; ++target)
|
||||
{
|
||||
*target = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Same as the above but with a loop around it.
|
||||
while (target < targetEnd)
|
||||
{
|
||||
if constexpr (sizeof(T) == 1)
|
||||
{
|
||||
memset(target, static_cast<unsigned char>(value), width * sizeof(T));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto it = target, end = it + width; it < end; ++it)
|
||||
{
|
||||
*it = value;
|
||||
}
|
||||
}
|
||||
|
||||
target += targetStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,12 +336,20 @@ CATCH_RETURN()
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void AtlasEngine::_fillColorBitmap(const size_t y, const size_t x1, const size_t x2, const u32 fgColor, const u32 bgColor) noexcept
|
||||
void AtlasEngine::_fillColorBitmap(size_t y, size_t x1, size_t x2, const u32 fgColor, const u32 bgColor) noexcept
|
||||
{
|
||||
// Never trust the caller. Do bounds checks.
|
||||
// The caller was written by yesterday's me and that person is a complete fool.
|
||||
y = clamp<size_t>(y, 0, _p.s->viewportCellCount.y);
|
||||
|
||||
const auto shift = _p.rows[y]->lineRendition != LineRendition::SingleWidth ? 1 : 0;
|
||||
// Ensure that x1 <= x2 and x2 <= width.
|
||||
x2 = clamp<size_t>(x2 << shift, 0, _p.s->viewportCellCount.x);
|
||||
x1 = clamp<size_t>(x1 << shift, 0, x2);
|
||||
|
||||
const auto bitmap = _p.colorBitmap.begin() + _p.colorBitmapRowStride * y;
|
||||
const auto shift = gsl::narrow_cast<u8>(_p.rows[y]->lineRendition != LineRendition::SingleWidth);
|
||||
auto beg = bitmap + (x1 << shift);
|
||||
auto end = bitmap + (x2 << shift);
|
||||
auto beg = bitmap + x1;
|
||||
auto end = bitmap + x2;
|
||||
|
||||
const u32 colors[] = {
|
||||
u32ColorPremultiply(bgColor),
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "pch.h"
|
||||
#include "BackendD3D.h"
|
||||
|
||||
#include <til/bytes.h>
|
||||
#include <til/unicode.h>
|
||||
|
||||
#include <custom_shader_ps.h>
|
||||
@@ -1067,18 +1068,12 @@ void BackendD3D::_uploadBackgroundBitmap(const RenderingPayload& p)
|
||||
D3D11_MAPPED_SUBRESOURCE mapped{};
|
||||
THROW_IF_FAILED(p.deviceContext->Map(_backgroundBitmap.get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped));
|
||||
|
||||
auto src = std::bit_cast<const char*>(p.backgroundBitmap.data());
|
||||
const auto srcEnd = std::bit_cast<const char*>(p.backgroundBitmap.data() + p.backgroundBitmap.size());
|
||||
const auto srcWidth = p.s->viewportCellCount.x * sizeof(u32);
|
||||
const auto src = std::bit_cast<const char*>(p.backgroundBitmap.data());
|
||||
const auto srcStride = p.colorBitmapRowStride * sizeof(u32);
|
||||
auto dst = static_cast<char*>(mapped.pData);
|
||||
const auto srcSize = p.backgroundBitmap.size();
|
||||
const auto dst = static_cast<char*>(mapped.pData);
|
||||
|
||||
while (src < srcEnd)
|
||||
{
|
||||
memcpy(dst, src, srcWidth);
|
||||
src += srcStride;
|
||||
dst += mapped.RowPitch;
|
||||
}
|
||||
til::bytes_strided_copy(dst, mapped.RowPitch, mapped.DepthPitch, src, srcStride, srcSize);
|
||||
|
||||
p.deviceContext->Unmap(_backgroundBitmap.get(), 0);
|
||||
_backgroundBitmapGeneration = p.colorBitmapGenerations[0];
|
||||
|
||||
Reference in New Issue
Block a user