Compare commits

..

1 Commits

Author SHA1 Message Date
Leonard Hecker
fa81e700ff Use native sRGB support for blending 2024-02-18 16:02:34 +01:00
22 changed files with 400 additions and 468 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -78,9 +78,6 @@ extends:
cloudvault: # https://aka.ms/obpipelines/cloudvault
enabled: false
globalSdl: # https://aka.ms/obpipelines/sdl
asyncSdl:
enabled: true
tsaOptionsFile: 'build/config/tsa.json'
tsa:
enabled: true
configFile: '$(Build.SourcesDirectory)\build\config\tsa.json'

View File

@@ -1,275 +0,0 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "precomp.h"
#include "LogIO.h"
using namespace Microsoft::Console::Host::BinaryLogging;
LoggingDeviceComm::LoggingDeviceComm(IDeviceComm* loggee, const std::wstring_view file) :
_loggee(loggee),
_lastEvent(std::chrono::high_resolution_clock::now())
{
_dataArena.resize(1024);
_file.reset(CreateFileW(file.data(), GENERIC_WRITE | DELETE, FILE_SHARE_READ, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr));
USHORT processMachine{};
USHORT nativeMachine{};
THROW_IF_WIN32_BOOL_FALSE(IsWow64Process2(GetCurrentProcess(), &processMachine, &nativeMachine));
LogHeader header{};
header.Version = 1;
header.HostArchitecture = nativeMachine;
_writeInFull(&header, sizeof(LogHeader));
//_startLogThread();
}
[[nodiscard]] HRESULT LoggingDeviceComm::SetServerInformation(CD_IO_SERVER_INFORMATION* const pServerInfo) const
{
return _loggee->SetServerInformation(pServerInfo);
}
[[nodiscard]] HRESULT LoggingDeviceComm::ReadIo(PCONSOLE_API_MSG const pReplyMsg, CONSOLE_API_MSG* const pMessage) const
{
RETURN_IF_FAILED(_loggee->ReadIo(pReplyMsg, pMessage));
static constexpr uint32_t apiMsgLen{ sizeof(CONSOLE_API_MSG) - offsetof(CONSOLE_API_MSG, Descriptor) };
_writeDataWithHeader(LogPacketType::Read, _timeDelta(), apiMsgLen, &pMessage->Descriptor);
return S_OK;
}
[[nodiscard]] HRESULT LoggingDeviceComm::CompleteIo(CD_IO_COMPLETE* const pCompletion) const
{
return _loggee->CompleteIo(pCompletion);
}
[[nodiscard]] HRESULT LoggingDeviceComm::ReadInput(CD_IO_OPERATION* const pIoOperation) const
{
RETURN_IF_FAILED(_loggee->ReadInput(pIoOperation));
_writeDataWithHeader(LogPacketType::InputBuffer, _timeDelta(), pIoOperation->Buffer.Size, pIoOperation->Buffer.Data);
return S_OK;
}
[[nodiscard]] HRESULT LoggingDeviceComm::WriteOutput(CD_IO_OPERATION* const pIoOperation) const
{
return _loggee->WriteOutput(pIoOperation);
}
[[nodiscard]] HRESULT LoggingDeviceComm::AllowUIAccess() const
{
return _loggee->AllowUIAccess();
}
[[nodiscard]] ULONG_PTR LoggingDeviceComm::PutHandle(const void* handle)
{
auto upstreamMapping{ _loggee->PutHandle(handle) };
auto found{ std::find(_handleTable.begin(), _handleTable.end(), upstreamMapping) };
if (found == _handleTable.end())
{
// append, get pos
found = _handleTable.emplace(found, upstreamMapping);
}
return found - _handleTable.begin();
}
[[nodiscard]] void* LoggingDeviceComm::GetHandle(ULONG_PTR handleId) const
{
return _loggee->GetHandle(_handleTable.at(handleId));
}
void LoggingDeviceComm::DestroyHandle(ULONG_PTR handleId)
{
auto& pos{ _handleTable.at(handleId) };
_loggee->DestroyHandle(pos);
pos = 0;
}
uint64_t LoggingDeviceComm::_timeDelta() const
{
auto thisEventTime{ std::chrono::high_resolution_clock::now() };
int64_t delta{ (thisEventTime - _lastEvent).count() };
_lastEvent = thisEventTime;
return delta;
}
void LoggingDeviceComm::_writeInFull(void* buffer, const size_t length) const
{
auto remaining{ length };
DWORD written{};
while (WriteFile(_file.get(), reinterpret_cast<std::byte*>(buffer) + (length - remaining), gsl::narrow_cast<DWORD>(remaining), &written, nullptr) != 0)
{
if ((remaining -= written) == 0)
{
break;
}
}
if (remaining)
{
THROW_HR(E_BOUNDS);
}
}
void LoggingDeviceComm::_writeDataWithHeader(LogPacketType packetType, uint64_t timeDelta, size_t length, const void* buffer) const
{
auto fullPacketLen{ length + offsetof(LogPacketDescriptor, _PositionInFile) };
if (_dataArena.size() < fullPacketLen)
{
_dataArena.resize(fullPacketLen);
}
*(reinterpret_cast<LogPacketDescriptor*>(_dataArena.data())) = LogPacketDescriptor{ packetType, timeDelta, gsl::narrow_cast<uint32_t>(length) };
const auto bufferAsByte{ reinterpret_cast<const std::byte*>(buffer) };
std::copy(bufferAsByte, bufferAsByte + length, _dataArena.data() + (offsetof(LogPacketDescriptor, _PositionInFile)));
_writeInFull(_dataArena.data(), fullPacketLen);
}
void LoggingDeviceComm::_logThreadBody()
{
}
void LoggingDeviceComm::_startLogThread()
{
_logThread = std::thread{
[this]() {
_logThreadBody();
}
};
}
/******************************************************REPLAY********************************/
void LogReplayDeviceComm::_readInFull(void* buffer, const size_t length) const
{
/*
auto remaining{ length };
DWORD read{};
while (!!ReadFile(_file.get(), reinterpret_cast<std::byte*>(buffer) + (length - remaining), gsl::narrow_cast<DWORD>(remaining), &read, nullptr))
{
if ((remaining -= read) == 0)
{
break;
}
}
if (remaining)
{
THROW_HR(E_BOUNDS);
}
*/
if (length > _max - _off)
{
THROW_HR(E_BOUNDS);
}
memcpy(buffer, _fileMapView.get() + _off, length);
_off += length;
}
const LogPacketDescriptor& LogReplayDeviceComm::_readDescriptor() const
{
//LogPacketDescriptor descriptor{};
//auto filepos{ SetFilePointer(_file.get(), 0, nullptr, FILE_CURRENT) };
//_readInFull(&descriptor, offsetof(LogPacketDescriptor, _PositionInFile));
//descriptor._PositionInFile = filepos;
auto oldOff{ _off };
_off += offsetof(LogPacketDescriptor, _PositionInFile);
return *reinterpret_cast<LogPacketDescriptor*>(_fileMapView.get() + oldOff);
//return descriptor;
}
LogReplayDeviceComm::LogReplayDeviceComm(const std::wstring_view file, double timeDilation) :
_timeDilation(timeDilation)
{
_file.reset(CreateFileW(file.data(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr));
_fileMapping.reset(CreateFileMappingW(_file.get(), nullptr, PAGE_READONLY, 0, 0, nullptr));
THROW_HR_IF_NULL(E_FAIL, _fileMapping);
_fileMapView.reset(static_cast<std::byte*>(MapViewOfFile(_fileMapping.get(), FILE_MAP_READ, 0, 0, 0)));
THROW_HR_IF_NULL(E_FAIL, _fileMapView);
MEMORY_BASIC_INFORMATION mbi{};
VirtualQuery(_fileMapView.get(), &mbi, sizeof(mbi));
_max = mbi.RegionSize;
USHORT processMachine{};
USHORT nativeMachine{};
THROW_IF_WIN32_BOOL_FALSE(IsWow64Process2(GetCurrentProcess(), &processMachine, &nativeMachine));
LogHeader header{};
_readInFull(&header, sizeof(header));
if (nativeMachine != header.HostArchitecture)
{
MessageBoxW(nullptr, wil::str_printf<std::wstring>(L"This dump was created on a conhost of a different architecture (expected %2.02x, got %2.02x).", header.HostArchitecture, nativeMachine).c_str(), L"Error", MB_OK | MB_ICONERROR);
ExitProcess(1);
}
}
[[nodiscard]] HRESULT LogReplayDeviceComm::SetServerInformation(CD_IO_SERVER_INFORMATION* const) const
{
return S_OK;
}
[[nodiscard]] HRESULT LogReplayDeviceComm::ReadIo(PCONSOLE_API_MSG const, CONSOLE_API_MSG* const pMessage) const
{
auto requestStartTime{ std::chrono::high_resolution_clock::now() };
static constexpr uint32_t maxLen{ sizeof(CONSOLE_API_MSG) - offsetof(CONSOLE_API_MSG, Descriptor) };
auto& descriptor{ _readDescriptor() };
THROW_HR_IF(E_UNEXPECTED, descriptor.PacketType != LogPacketType::Read || descriptor.Length < maxLen);
_readInFull(&pMessage->Descriptor, descriptor.Length);
auto finishTime{ requestStartTime + std::chrono::nanoseconds(static_cast<long long>(descriptor.TimeDeltaInNs * _timeDilation)) };
if (finishTime > std::chrono::high_resolution_clock::now())
std::this_thread::sleep_until(finishTime);
return S_OK;
}
[[nodiscard]] HRESULT LogReplayDeviceComm::CompleteIo(CD_IO_COMPLETE* const) const
{
return S_OK;
}
[[nodiscard]] HRESULT LogReplayDeviceComm::ReadInput(CD_IO_OPERATION* const pIoOperation) const
{
auto requestStartTime{ std::chrono::high_resolution_clock::now() };
auto& descriptor{ _readDescriptor() };
THROW_HR_IF(E_UNEXPECTED, descriptor.PacketType != LogPacketType::InputBuffer);
_readInFull(static_cast<uint8_t*>(pIoOperation->Buffer.Data), descriptor.Length);
auto finishTime{ requestStartTime + std::chrono::nanoseconds(static_cast<long long>(descriptor.TimeDeltaInNs * _timeDilation)) };
if (finishTime > std::chrono::high_resolution_clock::now())
std::this_thread::sleep_until(finishTime);
return S_OK;
}
[[nodiscard]] HRESULT LogReplayDeviceComm::WriteOutput(CD_IO_OPERATION* const) const
{
return S_OK;
}
[[nodiscard]] HRESULT LogReplayDeviceComm::AllowUIAccess() const
{
return S_OK;
}
[[nodiscard]] ULONG_PTR LogReplayDeviceComm::PutHandle(const void* handle)
{
auto found{ std::find(_handleTable.begin(), _handleTable.end(), handle) };
if (found == _handleTable.end())
{
// append, get pos
found = _handleTable.emplace(found, const_cast<void*>(handle));
}
return found - _handleTable.begin();
}
[[nodiscard]] void* LogReplayDeviceComm::GetHandle(ULONG_PTR handleId) const
{
return _handleTable.at(handleId);
}
void LogReplayDeviceComm::DestroyHandle(ULONG_PTR handleId)
{
auto& pos{ _handleTable.at(handleId) };
pos = nullptr;
}

View File

@@ -1,111 +0,0 @@
/*++
Copyright (c) Microsoft Corporation
Licensed under the MIT license.
Module Name:
- LogIO.h
Abstract:
- TODO DH: Explain logging
Author:
- Dustin Howett (DuHowett) 2020-11-14
Revision History:
--*/
#pragma once
namespace Microsoft::Console::Host::BinaryLogging
{
enum class LogPacketType : uint16_t
{
Read = 1,
InputBuffer = 2,
};
#pragma pack(push, 1)
struct LogHeader
{
uint8_t Version;
uint16_t HostArchitecture;
};
struct LogPacketDescriptor
{
LogPacketType PacketType;
uint64_t TimeDeltaInNs;
uint32_t Length;
uint32_t _PositionInFile;
};
#pragma pack(pop)
class LoggingDeviceComm : public IDeviceComm
{
public:
LoggingDeviceComm(IDeviceComm* loggee, const std::wstring_view file);
~LoggingDeviceComm() = default;
[[nodiscard]] HRESULT SetServerInformation(_In_ CD_IO_SERVER_INFORMATION* const pServerInfo) const override;
[[nodiscard]] HRESULT ReadIo(_In_opt_ PCONSOLE_API_MSG const pReplyMsg,
_Out_ CONSOLE_API_MSG* const pMessage) const override;
[[nodiscard]] HRESULT CompleteIo(_In_ CD_IO_COMPLETE* const pCompletion) const override;
[[nodiscard]] HRESULT ReadInput(_In_ CD_IO_OPERATION* const pIoOperation) const override;
[[nodiscard]] HRESULT WriteOutput(_In_ CD_IO_OPERATION* const pIoOperation) const override;
[[nodiscard]] HRESULT AllowUIAccess() const override;
[[nodiscard]] ULONG_PTR PutHandle(const void* handle) override;
[[nodiscard]] void* GetHandle(ULONG_PTR handleId) const override;
void DestroyHandle(ULONG_PTR handleId) override;
[[nodiscard]] virtual HRESULT GetServerHandle(_Out_ HANDLE* pHandle) const { *pHandle = nullptr; return E_FAIL; }
private:
wil::unique_hfile _file;
IDeviceComm* _loggee;
mutable std::chrono::high_resolution_clock::time_point _lastEvent;
std::vector<ULONG_PTR> _handleTable;
uint64_t _timeDelta() const;
mutable std::vector<std::byte> _dataArena;
void _writeInFull(void* buffer, const size_t length) const;
void _writeDataWithHeader(LogPacketType packetType, uint64_t timeDelta, size_t length, const void* buffer) const;
std::thread _logThread;
void _logThreadBody();
void _startLogThread();
};
class LogReplayDeviceComm : public IDeviceComm
{
public:
LogReplayDeviceComm(const std::wstring_view file, double timeDilation = 1.0);
~LogReplayDeviceComm() = default;
[[nodiscard]] HRESULT SetServerInformation(_In_ CD_IO_SERVER_INFORMATION* const /*pServerInfo*/) const override;
[[nodiscard]] HRESULT ReadIo(_In_opt_ PCONSOLE_API_MSG const /*pReplyMsg*/,
_Out_ CONSOLE_API_MSG* const pMessage) const override;
[[nodiscard]] HRESULT CompleteIo(_In_ CD_IO_COMPLETE* const /*pCompletion*/) const override;
[[nodiscard]] HRESULT ReadInput(_In_ CD_IO_OPERATION* const pIoOperation) const override;
[[nodiscard]] HRESULT WriteOutput(_In_ CD_IO_OPERATION* const /*pIoOperation*/) const override;
[[nodiscard]] HRESULT AllowUIAccess() const override;
[[nodiscard]] ULONG_PTR PutHandle(const void* handle) override;
[[nodiscard]] void* GetHandle(ULONG_PTR handleId) const override;
void DestroyHandle(ULONG_PTR handleId) override;
[[nodiscard]] virtual HRESULT GetServerHandle(_Out_ HANDLE* pHandle) const { *pHandle = nullptr; return E_FAIL; }
private:
wil::unique_hfile _file;
double _timeDilation;
std::vector<void*> _handleTable;
wil::unique_handle _fileMapping;
wil::unique_mapview_ptr<std::byte> _fileMapView;
mutable ptrdiff_t _off{ 0 };
size_t _max{};
void _readInFull(void* buffer, const size_t length) const;
const LogPacketDescriptor& _readDescriptor() const;
};
}

View File

@@ -328,12 +328,7 @@ int CALLBACK wWinMain(
if (useV2)
#endif // TIL_FEATURE_LEGACYCONHOST_ENABLED
{
auto clientCommandLine{ args.GetClientCommandline() };
if (clientCommandLine.rfind(L".bin") != std::wstring::npos)
{
hr = Entrypoints::StartConsoleForAPIDump(&args);
}
else if (args.ShouldCreateServerHandle())
if (args.ShouldCreateServerHandle())
{
hr = Entrypoints::StartConsoleForCmdLine(args.GetClientCommandline().c_str(), &args);
}

View File

@@ -48,7 +48,6 @@
<ClCompile Include="..\VtApiRoutines.cpp" />
<ClCompile Include="..\VtInputThread.cpp" />
<ClCompile Include="..\VtIo.cpp" />
<ClCompile Include="..\LogIO.cpp" />
<ClCompile Include="..\writeData.cpp" />
<ClCompile Include="..\_output.cpp" />
<ClCompile Include="..\_stream.cpp" />
@@ -101,7 +100,6 @@
<ClInclude Include="..\VtApiRoutines.h" />
<ClInclude Include="..\VtInputThread.hpp" />
<ClInclude Include="..\VtIo.hpp" />
<ClInclude Include="..\LogIO.hpp" />
<ClInclude Include="..\writeData.hpp" />
<ClInclude Include="..\_output.h" />
<ClInclude Include="..\_stream.h" />

View File

@@ -442,17 +442,10 @@ void COOKED_READ_DATA::_handleChar(wchar_t wch, const DWORD modifiers)
// It's unclear whether the original intention was to write at the end of the buffer at all times or to implement an insert mode.
// I went with insert mode.
//
// The old implementation also failed to clear the end of the prompt if you pressed tab in the middle of it.
// You can reproduce this issue by launching cmd in an old conhost build and writing "<command that doesn't exist> foo",
// moving your cursor to the space past the <command> and pressing tab. Nothing will happen but the "foo" will be inaccessible.
// I've now fixed this behavior by adding an additional Replace() before the _flushBuffer() call that removes the tail end.
//
// It is important that we don't actually print that character out though, as it's only for the calling application to see.
// That's why we flush the contents before the insertion and then ensure that the _flushBuffer() call in Read() exits early.
const auto cursor = _buffer.GetCursorPosition();
_buffer.Replace(cursor, npos, nullptr, 0);
_flushBuffer();
_buffer.Replace(cursor, 0, &wch, 1);
_buffer.Replace(_buffer.GetCursorPosition(), 0, &wch, 1);
_buffer.MarkAsClean();
_controlKeyState = modifiers;

View File

@@ -26,7 +26,6 @@
#include "renderData.hpp"
#include "../renderer/base/renderer.hpp"
#include "LogIO.h"
#include "../inc/conint.h"
#include "tracing.hpp"
@@ -39,7 +38,6 @@
using namespace Microsoft::Console::Interactivity;
using namespace Microsoft::Console::Render;
using namespace Microsoft::Console::Host::BinaryLogging;
const UINT CONSOLE_EVENT_FAILURE_ID = 21790;
const UINT CONSOLE_LPC_PORT_FAILURE_ID = 21791;
@@ -52,20 +50,11 @@ try
if (!Globals.pDeviceComm)
{
// in rare circumstances (such as in the fuzzing harness), there will already be a device comm
if (!Server)
{
Globals.pDeviceComm = new LogReplayDeviceComm(args->GetClientCommandline(), 1.0);
}
else
{
auto underlyingComm{ new ConDrvDeviceComm(Server) };
Globals.pDeviceComm = new LoggingDeviceComm(underlyingComm, L"conhost_log.bin");
}
Globals.pDeviceComm = new ConDrvDeviceComm(Server);
}
Globals.launchArgs = *args;
// TODO(DH) These should be part of the dump/trace
Globals.uiOEMCP = GetOEMCP();
Globals.uiWindowsCP = GetACP();

View File

@@ -23,7 +23,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
using pointer = const til::rect*;
using reference = const til::rect&;
_bitmap_const_iterator(const dynamic_bitset<size_t, Allocator>& values, til::rect rc, ptrdiff_t pos) :
_bitmap_const_iterator(const dynamic_bitset<unsigned long long, Allocator>& values, til::rect rc, ptrdiff_t pos) :
_values(values),
_rc(rc),
_pos(pos),
@@ -77,7 +77,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
}
private:
const dynamic_bitset<size_t, Allocator>& _values;
const dynamic_bitset<unsigned long long, Allocator>& _values;
const til::rect _rc;
size_t _pos;
size_t _nextPos;
@@ -133,7 +133,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
}
};
template<typename Allocator = std::allocator<size_t>>
template<typename Allocator = std::allocator<unsigned long long>>
class bitmap
{
public:
@@ -538,7 +538,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
allocator_type _alloc;
til::size _sz;
til::rect _rc;
dynamic_bitset<size_t, allocator_type> _bits;
dynamic_bitset<unsigned long long, allocator_type> _bits;
mutable std::optional<std::vector<til::rect, run_allocator_type>> _runs;
@@ -553,7 +553,7 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
namespace pmr
{
using bitmap = ::til::details::bitmap<std::pmr::polymorphic_allocator<size_t>>;
using bitmap = ::til::details::bitmap<std::pmr::polymorphic_allocator<unsigned long long>>;
}
}

View File

@@ -265,7 +265,12 @@ void BackendD3D::_handleSettingsUpdate(const RenderingPayload& p)
{
wil::com_ptr<ID3D11Texture2D> buffer;
THROW_IF_FAILED(p.swapChain.swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(buffer.addressof())));
THROW_IF_FAILED(p.device->CreateRenderTargetView(buffer.get(), nullptr, _renderTargetView.put()));
static constexpr D3D11_RENDER_TARGET_VIEW_DESC desc{
.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB,
.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D,
};
THROW_IF_FAILED(p.device->CreateRenderTargetView(buffer.get(), &desc, _renderTargetView.put()));
}
const auto fontChanged = _fontGeneration != p.s->font.generation();
@@ -547,7 +552,7 @@ void BackendD3D::_recreateBackgroundColorBitmap(const RenderingPayload& p)
.Height = p.s->viewportCellCount.y,
.MipLevels = 1,
.ArraySize = 1,
.Format = DXGI_FORMAT_R8G8B8A8_UNORM,
.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
.SampleDesc = { 1, 0 },
.Usage = D3D11_USAGE_DYNAMIC,
.BindFlags = D3D11_BIND_SHADER_RESOURCE,

View File

@@ -35,6 +35,7 @@ float3 DWrite_EnhanceContrast3(float3 alpha, float k)
return alpha * (k + 1.0f) / (alpha * k + 1.0f);
}
// dwrite vs. gamma 1.8: https://www.desmos.com/calculator/6wocsr6vcq
float DWrite_ApplyAlphaCorrection(float a, float f, float4 g)
{
return a + a * (1 - a) * ((g.x * f + g.y) * a + (g.z * f + g.w));

View File

@@ -27,7 +27,7 @@ struct PSData
float4 position : SV_Position;
float2 texcoord : texcoord;
nointerpolation uint shadingType : shadingType;
nointerpolation uint2 renditionScale : renditionScale;
nointerpolation float2 renditionScale : renditionScale;
nointerpolation float4 color : color;
};

View File

@@ -44,27 +44,13 @@ Output main(PSData data) : SV_Target
}
case SHADING_TYPE_TEXT_GRAYSCALE:
{
// These are independent of the glyph texture and could be moved to the vertex shader or CPU side of things.
const float4 foreground = premultiplyColor(data.color);
const float blendEnhancedContrast = DWrite_ApplyLightOnDarkContrastAdjustment(enhancedContrast, data.color.rgb);
const float intensity = DWrite_CalcColorIntensity(data.color.rgb);
// These aren't.
const float4 glyph = glyphAtlas[data.texcoord];
const float contrasted = DWrite_EnhanceContrast(glyph.a, blendEnhancedContrast);
const float alphaCorrected = DWrite_ApplyAlphaCorrection(contrasted, intensity, gammaRatios);
color = alphaCorrected * foreground;
color = glyphAtlas[data.texcoord].a * data.color;
weights = color.aaaa;
break;
}
case SHADING_TYPE_TEXT_CLEARTYPE:
{
// These are independent of the glyph texture and could be moved to the vertex shader or CPU side of things.
const float blendEnhancedContrast = DWrite_ApplyLightOnDarkContrastAdjustment(enhancedContrast, data.color.rgb);
// These aren't.
const float4 glyph = glyphAtlas[data.texcoord];
const float3 contrasted = DWrite_EnhanceContrast3(glyph.rgb, blendEnhancedContrast);
const float3 alphaCorrected = DWrite_ApplyAlphaCorrection3(contrasted, data.color.rgb, gammaRatios);
weights = float4(alphaCorrected * data.color.a, 1);
weights = float4(glyphAtlas[data.texcoord].rgb * data.color.a, 1);
color = weights * data.color;
break;
}
@@ -77,14 +63,14 @@ Output main(PSData data) : SV_Target
case SHADING_TYPE_DOTTED_LINE:
{
const bool on = frac(data.position.x / (2.0f * underlineWidth * data.renditionScale.x)) < 0.5f;
color = on * premultiplyColor(data.color);
color = on * data.color;
weights = color.aaaa;
break;
}
case SHADING_TYPE_DASHED_LINE:
{
const bool on = frac(data.position.x / (backgroundCellSize.x * data.renditionScale.x)) < 0.5f;
color = on * premultiplyColor(data.color);
color = on * data.color;
weights = color.aaaa;
break;
}
@@ -102,13 +88,13 @@ Output main(PSData data) : SV_Target
const float s = sin(data.position.x * freq);
const float d = abs(centerY - (s * amp) - data.position.y);
const float a = 1 - saturate(d - strokeWidthHalf);
color = a * premultiplyColor(data.color);
color = a * data.color;
weights = color.aaaa;
break;
}
default:
{
color = premultiplyColor(data.color);
color = data.color;
weights = color.aaaa;
break;
}

View File

@@ -3,6 +3,8 @@
#include "shader_common.hlsl"
#pragma warning(disable: 3571) // pow(f, e) will not work for negative f, use abs(f) or conditionally handle negative values if you expect them
cbuffer ConstBuffer : register(b0)
{
float2 positionScale;
@@ -13,7 +15,7 @@ PSData main(VSData data)
// clang-format on
{
PSData output;
output.color = data.color;
output.color = float4(pow(data.color.rgb * data.color.a, 2.2), data.color.a);
output.shadingType = data.shadingType;
output.renditionScale = data.renditionScale;
// positionScale is expected to be float2(2.0f / sizeInPixel.x, -2.0f / sizeInPixel.y). Together with the

View File

@@ -172,11 +172,6 @@ ConDrvDeviceComm::~ConDrvDeviceComm() = default;
return reinterpret_cast<void*>(handleId);
}
void ConDrvDeviceComm::DestroyHandle(ULONG_PTR /*handleId*/)
{
// nothing
}
// Routine Description:
// - Provides access to the raw server handle so it can be used to hand off
// the session to another console host server.

View File

@@ -39,7 +39,6 @@ public:
[[nodiscard]] ULONG_PTR PutHandle(const void*) override;
[[nodiscard]] void* GetHandle(ULONG_PTR) const override;
void DestroyHandle(ULONG_PTR) override;
[[nodiscard]] HRESULT GetServerHandle(_Out_ HANDLE* pHandle) const override;

View File

@@ -35,7 +35,6 @@ public:
[[nodiscard]] virtual ULONG_PTR PutHandle(const void*) = 0;
[[nodiscard]] virtual void* GetHandle(ULONG_PTR) const = 0;
virtual void DestroyHandle(ULONG_PTR) = 0;
[[nodiscard]] virtual HRESULT GetServerHandle(_Out_ HANDLE* pHandle) const = 0;
};

View File

@@ -176,16 +176,4 @@
FAIL_FAST_HR(E_UNEXPECTED);
return S_OK;
}
[[nodiscard]] HRESULT Entrypoints::StartConsoleForAPIDump(const ConsoleArguments* const args)
{
// Create a scope because we're going to exit thread if everything goes well.
// This scope will ensure all C++ objects and smart pointers get a chance to destruct before ExitThread is called.
RETURN_IF_FAILED(ConsoleCreateIoThreadLegacy(nullptr, args));
ExitThread(S_OK);
// We won't hit this. The ExitThread above will kill the caller at this point.
FAIL_FAST_HR(E_UNEXPECTED);
return S_OK;
}
#pragma warning(pop)

View File

@@ -22,5 +22,4 @@ namespace Entrypoints
{
[[nodiscard]] HRESULT StartConsoleForServerHandle(const HANDLE ServerHandle, const ConsoleArguments* const args);
[[nodiscard]] HRESULT StartConsoleForCmdLine(_In_ PCWSTR pwszCmdLine, const ConsoleArguments* const args);
[[nodiscard]] HRESULT StartConsoleForAPIDump(const ConsoleArguments* const args);
};

View File

@@ -147,4 +147,4 @@
<ItemGroup>
<Natvis Include="$(SolutionDir)tools\ConsoleTypes.natvis" />
</ItemGroup>
</Project>
</Project>

View File

@@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net461</TargetFramework>
<TargetFramework>net472</TargetFramework>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<LangVersion>latest</LangVersion>
</PropertyGroup>

View File

@@ -20,6 +20,14 @@
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>