chore: 删除旧版 EffectCompiler

This commit is contained in:
Xu 2026-03-24 11:52:59 +08:00
commit eadbf0e4d0
16 changed files with 99 additions and 2033 deletions

View file

@ -16,10 +16,11 @@
//!MAGPIE EFFECT
//!VERSION 4
//!VERSION 5
//!SORT_NAME CuNNy-03x12
//!USE MulAdd
//!CAPABILITY FP16
//!SCALE_FACTOR 2
#include "../StubDefs.hlsli"
@ -27,8 +28,6 @@
Texture2D INPUT;
//!TEXTURE
//!WIDTH INPUT_WIDTH * 2
//!HEIGHT INPUT_HEIGHT * 2
Texture2D OUTPUT;
//!SAMPLER

View file

@ -2,8 +2,7 @@
// 移植自 https://github.com/libretro/common-shaders/blob/master/windowed/shaders/lanczos6.cg
//!MAGPIE EFFECT
//!VERSION 4
//!VERSION 5
//!PARAMETER
//!LABEL Anti-ringing Strength
@ -23,7 +22,6 @@ Texture2D OUTPUT;
//!FILTER POINT
SamplerState sam;
//!PASS 1
//!STYLE PS
//!IN INPUT

File diff suppressed because it is too large Load diff

View file

@ -73,7 +73,6 @@
<ClInclude Include="GraphicsCaptureFrameSource.h" />
<ClInclude Include="D3D12Context.h" />
<ClInclude Include="include\DirectXHelper.h" />
<ClInclude Include="include\EffectCompiler.h" />
<ClInclude Include="include\EffectDesc.h" />
<ClInclude Include="include\ScalingOptions.h" />
<ClInclude Include="include\ScalingRuntime.h" />
@ -99,7 +98,6 @@
<ClCompile Include="DirtyRectsOptimizer.cpp" />
<ClCompile Include="DuplicateFrameChecker.cpp" />
<ClCompile Include="DescriptorHeap.cpp" />
<ClCompile Include="EffectCompiler.cpp" />
<ClCompile Include="EffectsDrawer.cpp" />
<ClCompile Include="ExclModeHelper.cpp" />
<ClCompile Include="FrameProducer.cpp" />

View file

@ -33,9 +33,6 @@
</ClInclude>
<ClInclude Include="ScalingWindow.h" />
<ClInclude Include="CursorManager.h" />
<ClInclude Include="include\EffectCompiler.h">
<Filter>Include</Filter>
</ClInclude>
<ClInclude Include="include\EffectDesc.h">
<Filter>Include</Filter>
</ClInclude>
@ -136,7 +133,6 @@
<ItemGroup>
<ClCompile Include="ScalingRuntime.cpp" />
<ClCompile Include="pch.cpp" />
<ClCompile Include="EffectCompiler.cpp" />
<ClCompile Include="DirectXHelper.cpp">
<Filter>Helpers</Filter>
</ClCompile>

View file

@ -371,8 +371,8 @@ static bool ResolveHeaderVersion(
return false;
}
// 向后兼容到 4
if (version < 4 || version > MAGPIE_FX_VERSION) {
// 向后兼容到 5
if (version < 5 || version > MAGPIE_FX_VERSION) {
return false;
}
@ -449,6 +449,22 @@ static bool ResolveHeaderCapability(
return true;
}
static bool ResolveHeaderScaleFactor(
std::string_view& source,
ParserState& state,
void* data
) noexcept {
if (!GetNextNumber(source, state, ((EffectInfo2*)data)->scaleFactor)) {
return false;
}
if (!RequireLineEnd(source, state)) {
return false;
}
return true;
}
static bool ResolveHeader(
std::string_view source,
uint32_t startLineNumer,
@ -458,7 +474,8 @@ static bool ResolveHeader(
CommandInfo{ "VERSION", ResolveHeaderVersion, true },
CommandInfo{ "SORT_NAME", ResolveHeaderSortName, false },
CommandInfo{ "USE", ResolveHeaderUse, false },
CommandInfo{ "CAPABILITY", ResolveHeaderCapability, false }
CommandInfo{ "CAPABILITY", ResolveHeaderCapability, false },
CommandInfo{ "SCALE_FACTOR", ResolveHeaderScaleFactor, false },
};
ParserState state = {

View file

@ -1,27 +0,0 @@
#pragma once
#include <parallel_hashmap/phmap.h>
namespace Magpie {
struct EffectCompilerFlags {
// 会影响编译出的字节码的标志放在低 16 位中,这样组织是为了便于缓存
static constexpr uint32_t InlineParams = 1;
static constexpr uint32_t NoFP16 = 1 << 1;
// 只解析输出尺寸和参数,供用户界面使用
static constexpr uint32_t NoCompile = 1 << 16;
static constexpr uint32_t NoCache = 1 << 17;
static constexpr uint32_t SaveSources = 1 << 18;
static constexpr uint32_t WarningsAreErrors = 1 << 19;
};
struct EffectCompiler {
// 调用者需填入 desc 中的 name 和 flags
static uint32_t Compile(
struct EffectDesc& desc,
uint32_t flags, // EffectCompilerFlags
const phmap::flat_hash_map<std::string, float>* inlineParams = nullptr
) noexcept;
};
}

View file

@ -23,8 +23,8 @@ struct EffectInfo2 {
std::string name;
std::string sortName;
std::vector<EffectInfoParameter> params;
// 可使用 INPUT_WIDTH空字符串表示支持自由缩放
std::pair<std::string, std::string> outputSizeExprs;
// 0 表示可以自由缩放
uint32_t scaleFactor = 0;
EffectInfoFlags2 flags = EffectInfoFlags2::None;
};

View file

@ -14,7 +14,6 @@
#include "ScalingModesService.h"
#include "ScalingMode.h"
#include "EffectsService.h"
#include "EffectDesc.h"
#include "App.h"
using namespace Magpie;
@ -67,7 +66,7 @@ EffectParametersViewModel::EffectParametersViewModel(uint32_t scalingModeIdx, ui
std::vector<IInspectable> boolParams;
std::vector<IInspectable> floatParams;
for (uint32_t i = 0, size = (uint32_t)_effectInfo->params.size(); i < size; ++i) {
const EffectParameterDesc& param = _effectInfo->params[i];
const EffectInfoParameter& param = _effectInfo->params[i];
std::optional<float> paramValue;
{
@ -76,41 +75,31 @@ EffectParametersViewModel::EffectParametersViewModel(uint32_t scalingModeIdx, ui
paramValue = it->second;
}
}
if (param.constant.index() == 0) {
const EffectConstant<float>& constant = std::get<0>(param.constant);
// 只有 0 和 1 两个值的参数使用复选框
if (IsApprox(param.minValue, 0.0f) && IsApprox(param.maxValue, 1.0f) && IsApprox(param.step, 1.0f)) {
auto boolParamItem = make_self<ScalingModeBoolParameter>(
i,
hstring(StrHelper::UTF8ToUTF16(param.label.empty() ? param.name : param.label)),
paramValue.has_value() ?
std::abs(*paramValue) > FLOAT_EPSILON<float> :
(std::lround(param.defaultValue) == 1)
);
boolParamItem->PropertyChanged(
{ this, &EffectParametersViewModel::_ScalingModeBoolParameter_PropertyChanged });
boolParams.push_back(*boolParamItem);
} else {
auto floatParamItem = make_self<ScalingModeFloatParameter>(
i,
hstring(StrHelper::UTF8ToUTF16(param.label.empty() ? param.name : param.label)),
paramValue.has_value() ? *paramValue : constant.defaultValue,
constant.minValue,
constant.maxValue,
constant.step
paramValue.has_value() ? *paramValue : param.defaultValue,
param.minValue,
param.maxValue,
param.step
);
floatParamItem->PropertyChanged({ this, &EffectParametersViewModel::_ScalingModeFloatParameter_PropertyChanged });
floatParamItem->PropertyChanged(
{ this, &EffectParametersViewModel::_ScalingModeFloatParameter_PropertyChanged });
floatParams.push_back(*floatParamItem);
} else {
const EffectConstant<int>& constant = std::get<1>(param.constant);
if (constant.minValue == 0 && constant.maxValue == 1 && constant.step == 1) {
auto boolParamItem = make_self<ScalingModeBoolParameter>(
i,
hstring(StrHelper::UTF8ToUTF16(param.label.empty() ? param.name : param.label)),
paramValue.has_value() ? std::abs(*paramValue) > FLOAT_EPSILON<float> : (bool)constant.defaultValue
);
boolParamItem->PropertyChanged({ this, &EffectParametersViewModel::_ScalingModeBoolParameter_PropertyChanged });
boolParams.push_back(*boolParamItem);
} else {
auto floatParamItem = make_self<ScalingModeFloatParameter>(
i,
hstring(StrHelper::UTF8ToUTF16(param.label.empty() ? param.name : param.label)),
paramValue.has_value() ? *paramValue : (float)constant.defaultValue,
(float)constant.minValue,
(float)constant.maxValue,
(float)constant.step
);
floatParamItem->PropertyChanged({ this, &EffectParametersViewModel::_ScalingModeFloatParameter_PropertyChanged });
floatParams.push_back(*floatParamItem);
}
}
}
if (!boolParams.empty()) {

View file

@ -5,7 +5,7 @@
#include <parallel_hashmap/phmap.h>
namespace Magpie {
struct EffectInfo;
struct EffectInfo2;
}
namespace winrt::Magpie::implementation {
@ -134,7 +134,7 @@ private:
uint32_t _scalingModeIdx;
uint32_t _effectIdx;
const ::Magpie::EffectInfo* _effectInfo = nullptr;
const ::Magpie::EffectInfo2* _effectInfo = nullptr;
};
}

View file

@ -1,22 +1,13 @@
#include "pch.h"
#include "CommonSharedConstants.h"
#include "EffectCompiler.h"
#include "ShaderEffectParser.h"
#include "EffectDesc.h"
#include "EffectInfo.h"
#include "EffectsService.h"
#include "Logger.h"
#include "StrHelper.h"
#include "Win32Helper.h"
using namespace winrt;
namespace Magpie {
EffectInfo::EffectInfo() {}
EffectInfo::~EffectInfo() {}
static void ListEffects(std::vector<std::wstring>& result, std::wstring_view prefix = {}) {
result.reserve(80);
@ -49,8 +40,8 @@ static void ListEffects(std::vector<std::wstring>& result, std::wstring_view pre
} while (FindNextFile(hFind.get(), &findData));
}
fire_and_forget EffectsService::Initialize() {
co_await resume_background();
winrt::fire_and_forget EffectsService::Initialize() {
co_await winrt::resume_background();
std::vector<std::wstring> effectNames;
ListEffects(effectNames);
@ -64,48 +55,20 @@ fire_and_forget EffectsService::Initialize() {
// 并行解析效果
Win32Helper::RunParallel([&](uint32_t id) {
EffectDesc effectDesc;
{
std::wstring fileName = StrHelper::Concat(
CommonSharedConstants::EFFECTS_DIR, L"\\", effectNames[id], L".hlsl");
std::string source;
Win32Helper::ReadTextFile(fileName.c_str(), source);
EffectInfo2 effectInfo;
ShaderEffectParser::ParseForInfo(
StrHelper::UTF16ToUTF8(effectNames[id]), std::move(source), effectInfo);
}
effectDesc.name = StrHelper::UTF16ToUTF8(effectNames[id]);
if (EffectCompiler::Compile(effectDesc, EffectCompilerFlags::NoCompile)) {
std::wstring fileName = StrHelper::Concat(
CommonSharedConstants::EFFECTS_DIR, L"\\", effectNames[id], L".hlsl");
std::string source;
Win32Helper::ReadTextFile(fileName.c_str(), source);
EffectInfo2 effectInfo;
std::string errorMsg = ShaderEffectParser::ParseForInfo(
StrHelper::UTF16ToUTF8(effectNames[id]), std::move(source), effectInfo);
if (!errorMsg.empty()) {
return;
}
EffectInfo effect;
effect.name = std::move(effectNames[id]);
if (effectDesc.sortName.empty()) {
effect.sortName = effect.name;
} else {
size_t pos = effect.name.find_last_of(L'\\');
if (pos == std::wstring::npos) {
effect.sortName = StrHelper::UTF8ToUTF16(effectDesc.sortName);
} else {
effect.sortName = StrHelper::Concat(
std::wstring_view(effect.name.c_str(), pos + 1),
StrHelper::UTF8ToUTF16(effectDesc.sortName)
);
}
}
effect.params = std::move(effectDesc.params);
if (effectDesc.GetOutputSizeExpr().first.empty()) {
effect.flags |= EffectInfoFlags::CanScale;
}
auto lock = srwLock.lock_exclusive();
_effectsMap.emplace(effect.name, (uint32_t)_effects.size());
_effects.emplace_back(std::move(effect));
_effectsMap.emplace(effectNames[id], (uint32_t)_effects.size());
_effects.emplace_back(std::move(effectInfo));
}, nEffect);
_initialized.store(true, std::memory_order_release);
@ -117,12 +80,12 @@ void EffectsService::Uninitialize() {
_WaitForInitialize();
}
const std::vector<EffectInfo>& EffectsService::Effects() noexcept {
const std::vector<EffectInfo2>& EffectsService::GetEffects() noexcept {
_WaitForInitialize();
return _effects;
}
const EffectInfo* EffectsService::GetEffect(std::wstring_view name) noexcept {
const EffectInfo2* EffectsService::GetEffect(std::wstring_view name) noexcept {
_WaitForInitialize();
auto it = _effectsMap.find(name);

View file

@ -1,28 +1,9 @@
#pragma once
#include <parallel_hashmap/phmap.h>
#include "EffectInfo.h"
namespace Magpie {
struct EffectParameterDesc;
struct EffectInfoFlags {
static constexpr uint32_t CanScale = 1;
};
struct EffectInfo {
EffectInfo();
~EffectInfo();
std::wstring name;
std::wstring sortName;
std::vector<EffectParameterDesc> params;
uint32_t flags = 0; // EffectInfoFlags
bool CanScale() const noexcept {
return flags & EffectInfoFlags::CanScale;
}
};
class EffectsService {
public:
static EffectsService& Get() noexcept {
@ -37,16 +18,17 @@ public:
void Uninitialize();
const std::vector<EffectInfo>& Effects() noexcept;
const std::vector<EffectInfo2>& GetEffects() noexcept;
const EffectInfo* GetEffect(std::wstring_view name) noexcept;
// 由于 WinUI 使用 UTF-16这里也以 UTF-16 作为参数以减少编码转换
const EffectInfo2* GetEffect(std::wstring_view name) noexcept;
private:
EffectsService() = default;
void _WaitForInitialize() noexcept;
std::vector<EffectInfo> _effects;
std::vector<EffectInfo2> _effects;
phmap::flat_hash_map<std::wstring, uint32_t> _effectsMap;
std::atomic<bool> _initialized = false;
bool _initializedCache = false;

View file

@ -72,7 +72,7 @@ bool ScalingModeEffectItem::CanScale() const noexcept {
return false;
}
return _effectInfo && _effectInfo->CanScale();
return _effectInfo && _effectInfo->scaleFactor == 0;
}
bool ScalingModeEffectItem::HasParameters() const noexcept {

View file

@ -95,7 +95,7 @@ private:
uint32_t _scalingModeIdx = 0;
uint32_t _effectIdx = 0;
hstring _name;
const ::Magpie::EffectInfo* _effectInfo = nullptr;
const ::Magpie::EffectInfo2* _effectInfo = nullptr;
com_ptr<EffectParametersViewModel> _parametersViewModel;
};

View file

@ -215,9 +215,9 @@ void ScalingModeItem::AddEffect(const hstring& fullName) {
EffectItem& effect = _Data().effects.emplace_back();
effect.name = fullName;
const EffectInfo* effectInfo = EffectsService::Get().GetEffect(fullName);
const EffectInfo2* effectInfo = EffectsService::Get().GetEffect(fullName);
assert(effectInfo);
if (effectInfo->CanScale()) {
if (effectInfo->scaleFactor == 0) {
// 支持缩放的效果默认等比缩放到充满屏幕
effect.scalingType = ::Magpie::ScalingType::Fit;
}

View file

@ -5,6 +5,7 @@
#endif
#include "ControlHelper.h"
#include "EffectsService.h"
#include "StrHelper.h"
#include <parallel_hashmap/phmap.h>
using namespace ::Magpie;
@ -72,47 +73,47 @@ void ScalingModesPage::RemoveScalingModeMenuItem_Click(IInspectable const& sende
void ScalingModesPage::_BuildEffectMenu() noexcept {
std::vector<MenuFlyoutItemBase> rootItems;
phmap::flat_hash_map<std::wstring_view, MenuFlyoutSubItem> folders;
folders.reserve(13);
for (const auto& effect : EffectsService::Get().Effects()) {
std::wstring_view name(effect.name);
phmap::flat_hash_map<std::wstring, MenuFlyoutSubItem> folders;
folders.reserve(8);
for (const EffectInfo2& effectInfo : EffectsService::Get().GetEffects()) {
std::wstring effectName(StrHelper::UTF8ToUTF16(effectInfo.name));
MenuFlyoutItem item;
item.Tag(box_value(effect.name));
item.Tag(box_value(effectName));
item.Click({ this, &ScalingModesPage::_AddEffectMenuFlyoutItem_Click });
size_t delimPos = name.find_last_of(L'\\');
size_t delimPos = effectName.find_last_of(L'\\');
if (delimPos == std::wstring::npos) {
item.Text(name);
item.Text(effectName);
rootItems.emplace_back(std::move(item));
continue;
}
item.Text(name.substr(delimPos + 1));
item.Text(std::wstring_view(effectName.begin() + delimPos + 1, effectName.end()));
std::wstring_view dir = name.substr(0, delimPos);
std::wstring dir = effectName.substr(0, delimPos);
auto it = folders.find(dir);
if (it != folders.end()) {
it->second.Items().Append(item);
} else {
MenuFlyoutSubItem folder;
folder.Text(hstring(dir));
folder.Text(dir);
folder.Items().Append(item);
rootItems.push_back(folder);
folders.emplace(dir, folder);
folders.emplace(std::move(dir), folder);
}
}
std::sort(rootItems.begin(), rootItems.end(), [](MenuFlyoutItemBase const& l, MenuFlyoutItemBase const& r) {
bool isLSubMenu = get_class_name(l) == name_of<MenuFlyoutSubItem>();
bool isRSubMenu = get_class_name(r) == name_of<MenuFlyoutSubItem>();
bool isSubMenu1 = get_class_name(l) == name_of<MenuFlyoutSubItem>();
bool isSubMenu2 = get_class_name(r) == name_of<MenuFlyoutSubItem>();
if (isLSubMenu != isRSubMenu) {
return isLSubMenu;
if (isSubMenu1 != isSubMenu2) {
return isSubMenu1;
}
if (isLSubMenu) {
if (isSubMenu1) {
return l.try_as<MenuFlyoutSubItem>().Text() < r.try_as<MenuFlyoutSubItem>().Text();
} else {
return l.try_as<MenuFlyoutItem>().Text() < r.try_as<MenuFlyoutItem>().Text();
@ -131,13 +132,18 @@ void ScalingModesPage::_BuildEffectMenu() noexcept {
std::vector<MenuFlyoutItemBase> itemsVec(items.Size(), nullptr);
items.GetMany(0, itemsVec);
std::sort(itemsVec.begin(), itemsVec.end(), [](const MenuFlyoutItemBase& l, const MenuFlyoutItemBase& r) {
hstring lEffectName = unbox_value<hstring>(l.try_as<MenuFlyoutItem>().Tag());
hstring rEffectName = unbox_value<hstring>(r.try_as<MenuFlyoutItem>().Tag());
hstring name1 = unbox_value<hstring>(l.try_as<MenuFlyoutItem>().Tag());
hstring name2 = unbox_value<hstring>(r.try_as<MenuFlyoutItem>().Tag());
const EffectInfo* lEffectInfo = EffectsService::Get().GetEffect(lEffectName);
const EffectInfo* rEffectInfo = EffectsService::Get().GetEffect(rEffectName);
const EffectInfo2* effectInfo1 = EffectsService::Get().GetEffect(name1);
const EffectInfo2* effectInfo2 = EffectsService::Get().GetEffect(name2);
return lEffectInfo->sortName < rEffectInfo->sortName;
const std::string& sortName1 =
effectInfo1->sortName.empty() ? effectInfo1->name : effectInfo1->sortName;
const std::string& sortName2 =
effectInfo2->sortName.empty() ? effectInfo2->name : effectInfo2->sortName;
return sortName1 < sortName2;
});
items.ReplaceAll(itemsVec);
}