perf: 及时清理用于解析光标的临时资源

This commit is contained in:
Xu 2026-03-15 17:44:08 +08:00
commit f1739ba4e3
4 changed files with 49 additions and 20 deletions

View file

@ -271,6 +271,9 @@ HRESULT CursorDrawer::Draw(
Logger::Get().ComError("_InitializeCursorTexture 失败", hr);
return hr;
}
_curCursorInfo->originResourcesFenceValue = nextFenceValue;
_cursorInfosWithOriginResources.push_back(_curCursorInfo);
}
const RECT cursorRect = {
@ -1172,6 +1175,7 @@ void CursorDrawer::_ClearCursorInfos() noexcept {
}
_cursorInfos.clear();
_cursorInfosWithOriginResources.clear();
}
HRESULT CursorDrawer::_CreateColorPSO(
@ -1479,30 +1483,50 @@ HRESULT CursorDrawer::_CreateCursorResizerPSO() noexcept {
}
void CursorDrawer::_ClearRetiredResources(uint64_t completedFenceValue) noexcept {
if (_retiredTempOriginTextures.empty()) {
return;
}
// _retiredTempOriginTextures 中元素的 fenceValue 按升序排列
auto it = std::find_if(
_retiredTempOriginTextures.begin(),
_retiredTempOriginTextures.end(),
[&](const _RetiredTempOriginTexture& rt) {
return rt.fenceValue > completedFenceValue;
if (!_cursorInfosWithOriginResources.empty()) {
// fenceValue 按升序排列
auto it = std::find_if(
_cursorInfosWithOriginResources.begin(),
_cursorInfosWithOriginResources.end(),
[&](_CursorInfo* cursorInfo) {
return cursorInfo->originResourcesFenceValue > completedFenceValue;
}
);
if (it == _cursorInfosWithOriginResources.begin()) {
return;
}
);
if (it == _retiredTempOriginTextures.begin()) {
return;
}
auto& descriptorHeap = _d3d12Context->GetDescriptorHeap();
for (auto it1 = _retiredTempOriginTextures.begin(); it1 != it; ++it1) {
if (it1->srvOffset != std::numeric_limits<uint32_t>::max()) {
descriptorHeap.Free(it1->srvOffset, 1);
for (auto it1 = _cursorInfosWithOriginResources.begin(); it1 != it; ++it1) {
_CursorInfo& cursorInfo = **it1;
cursorInfo.originUploadBuffer = nullptr;
cursorInfo.originTexture = nullptr;
}
_cursorInfosWithOriginResources.erase(_cursorInfosWithOriginResources.begin(), it);
}
_retiredTempOriginTextures.erase(_retiredTempOriginTextures.begin(), it);
if (!_retiredTempOriginTextures.empty()) {
// fenceValue 按升序排列
auto it = std::find_if(
_retiredTempOriginTextures.begin(),
_retiredTempOriginTextures.end(),
[&](const _RetiredTempOriginTexture& rt) {
return rt.fenceValue > completedFenceValue;
}
);
if (it == _retiredTempOriginTextures.begin()) {
return;
}
auto& descriptorHeap = _d3d12Context->GetDescriptorHeap();
for (auto it1 = _retiredTempOriginTextures.begin(); it1 != it; ++it1) {
if (it1->srvOffset != std::numeric_limits<uint32_t>::max()) {
descriptorHeap.Free(it1->srvOffset, 1);
}
}
_retiredTempOriginTextures.erase(_retiredTempOriginTextures.begin(), it);
}
}
}

View file

@ -95,8 +95,10 @@ private:
Size originSize;
ByteBuffer originTextureData;
// 这两个纹理使用完毕后在 _ClearRetiredResources 中释放
winrt::com_ptr<ID3D12Resource> originUploadBuffer;
winrt::com_ptr<ID3D12Resource> originTexture;
uint64_t originResourcesFenceValue = 0;
uint32_t textureSrvOffset = std::numeric_limits<uint32_t>::max();
uint32_t textureRtvOffset = std::numeric_limits<uint32_t>::max();
@ -158,6 +160,9 @@ private:
// DPI 为 0 表示此光标不随 DPI 缩放
phmap::flat_hash_map<std::pair<HCURSOR, uint32_t>, _CursorInfo> _cursorInfos;
// 保存临时纹理资源未被释放的 _CursorInfo
SmallVector<_CursorInfo*, 1> _cursorInfosWithOriginResources;
// 保存解析失败的光标以避免重复尝试
phmap::flat_hash_set<HCURSOR> _unresolvableCursors;

View file

@ -1055,7 +1055,7 @@
<value>Use software rendering</value>
</data>
<data name="Home_Advanced_DeveloperOptions_HighestShaderModel.Header" xml:space="preserve">
<value>Highest shader model</value>
<value>Highest shader model version</value>
</data>
<data name="Home_Advanced_DeveloperOptions_HighestShaderModel_NotLimited.Content" xml:space="preserve">
<value>Not limited</value>

View file

@ -1055,7 +1055,7 @@
<value>使用软件渲染</value>
</data>
<data name="Home_Advanced_DeveloperOptions_HighestShaderModel.Header" xml:space="preserve">
<value>最高 shader model</value>
<value>最高 shader model 版本</value>
</data>
<data name="Home_Advanced_DeveloperOptions_HighestShaderModel_NotLimited.Content" xml:space="preserve">
<value>不限制</value>