Skip to content

Commit 17497bb

Browse files
committed
fix: 修复色域切换 bug
1 parent df05e9e commit 17497bb

File tree

8 files changed

+75
-61
lines changed

8 files changed

+75
-61
lines changed

src/Magpie.Core/CatmullRomEffectDrawer.cpp

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -93,22 +93,13 @@ HRESULT CatmullRomEffectDrawer::Initialize(
9393
}
9494
}
9595

96-
{
97-
D3D12_COMPUTE_PIPELINE_STATE_DESC psoDesc = {
98-
.pRootSignature = _rootSignature.get(),
99-
.CS = CD3DX12_SHADER_BYTECODE(
100-
_outputColorSpace == EffectColorSpace::sRGB ? CatmullRomCS_sRGB : CatmullRomCS,
101-
_outputColorSpace == EffectColorSpace::sRGB ? sizeof(CatmullRomCS_sRGB) : sizeof(CatmullRomCS)
102-
)
103-
};
104-
HRESULT hr = device->CreateComputePipelineState(&psoDesc, IID_PPV_ARGS(&_pipelineState));
105-
if (FAILED(hr)) {
106-
Logger::Get().ComError("CreateComputePipelineState 失败", hr);
107-
return hr;
108-
}
96+
HRESULT hr = _CreatePiplineState();
97+
if (FAILED(hr)) {
98+
Logger::Get().ComError("_CreatePiplineState 失败", hr);
99+
return hr;
109100
}
110101

111-
_CreateDisplayDependentResources(
102+
_CreateDescriptors(
112103
descriptorCpuHandle, descriptorGpuHandle, descriptorSize, inputResource, outputResource);
113104

114105
return S_OK;
@@ -165,11 +156,11 @@ void CatmullRomEffectDrawer::OnResized(
165156
_inputSize = inputSize;
166157
_outputSize = outputSize;
167158

168-
_CreateDisplayDependentResources(
159+
_CreateDescriptors(
169160
descriptorCpuHandle, descriptorGpuHandle, descriptorSize, inputResource, outputResource);
170161
}
171162

172-
void CatmullRomEffectDrawer::OnColorInfoChanged(
163+
HRESULT CatmullRomEffectDrawer::OnColorInfoChanged(
173164
EffectColorSpace inputColorSpace,
174165
EffectColorSpace outputColorSpace,
175166
CD3DX12_CPU_DESCRIPTOR_HANDLE& descriptorCpuHandle,
@@ -179,16 +170,47 @@ void CatmullRomEffectDrawer::OnColorInfoChanged(
179170
ID3D12Resource* outputResource
180171
) noexcept {
181172
if (_inputColorSpace == inputColorSpace && _outputColorSpace == outputColorSpace) {
182-
return;
173+
return S_OK;
183174
}
175+
184176
_inputColorSpace = inputColorSpace;
185-
_outputColorSpace = outputColorSpace;
186177

187-
_CreateDisplayDependentResources(
188-
descriptorCpuHandle, descriptorGpuHandle, descriptorSize, inputResource, outputResource);
178+
if (_outputColorSpace != outputColorSpace) {
179+
_outputColorSpace = outputColorSpace;
180+
181+
HRESULT hr = _CreatePiplineState();
182+
if (FAILED(hr)) {
183+
Logger::Get().ComError("_CreatePiplineState 失败", hr);
184+
return hr;
185+
}
186+
}
187+
188+
_CreateDescriptors(descriptorCpuHandle, descriptorGpuHandle,
189+
descriptorSize, inputResource, outputResource);
190+
191+
return S_OK;
192+
}
193+
194+
HRESULT CatmullRomEffectDrawer::_CreatePiplineState() noexcept {
195+
ID3D12Device5* device = _graphicsContext->GetDevice();
196+
197+
D3D12_COMPUTE_PIPELINE_STATE_DESC psoDesc = {
198+
.pRootSignature = _rootSignature.get(),
199+
.CS = CD3DX12_SHADER_BYTECODE(
200+
_outputColorSpace == EffectColorSpace::sRGB ? CatmullRomCS_sRGB : CatmullRomCS,
201+
_outputColorSpace == EffectColorSpace::sRGB ? sizeof(CatmullRomCS_sRGB) : sizeof(CatmullRomCS)
202+
)
203+
};
204+
HRESULT hr = device->CreateComputePipelineState(&psoDesc, IID_PPV_ARGS(&_pipelineState));
205+
if (FAILED(hr)) {
206+
Logger::Get().ComError("CreateComputePipelineState 失败", hr);
207+
return hr;
208+
}
209+
210+
return S_OK;
189211
}
190212

191-
void CatmullRomEffectDrawer::_CreateDisplayDependentResources(
213+
void CatmullRomEffectDrawer::_CreateDescriptors(
192214
CD3DX12_CPU_DESCRIPTOR_HANDLE& descriptorCpuHandle,
193215
CD3DX12_GPU_DESCRIPTOR_HANDLE& descriptorGpuHandle,
194216
uint32_t descriptorSize,

src/Magpie.Core/CatmullRomEffectDrawer.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class CatmullRomEffectDrawer : public EffectDrawerBase {
4646
ID3D12Resource* outputResource
4747
) noexcept;
4848

49-
void OnColorInfoChanged(
49+
HRESULT OnColorInfoChanged(
5050
EffectColorSpace inputColorSpace,
5151
EffectColorSpace outputColorSpace,
5252
CD3DX12_CPU_DESCRIPTOR_HANDLE& descriptorCpuHandle,
@@ -57,7 +57,9 @@ class CatmullRomEffectDrawer : public EffectDrawerBase {
5757
) noexcept;
5858

5959
private:
60-
void _CreateDisplayDependentResources(
60+
HRESULT _CreatePiplineState() noexcept;
61+
62+
void _CreateDescriptors(
6163
CD3DX12_CPU_DESCRIPTOR_HANDLE& descriptorCpuHandle,
6264
CD3DX12_GPU_DESCRIPTOR_HANDLE& descriptorGpuHandle,
6365
uint32_t descriptorSize,

src/Magpie.Core/EffectsDrawer.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,13 @@ HRESULT EffectsDrawer::OnColorInfoChanged(
226226
EffectColorSpace::sRGB : EffectColorSpace::scRGB;
227227
CD3DX12_CPU_DESCRIPTOR_HANDLE descriptorCpuHandle = _effectsDescriptorCpuBase;
228228
CD3DX12_GPU_DESCRIPTOR_HANDLE descriptorGpuHandle = _effectsDescriptorGpuBase;
229-
_catmullRom.OnColorInfoChanged(colorSpace, colorSpace, descriptorCpuHandle,
229+
HRESULT hr = _catmullRom.OnColorInfoChanged(colorSpace, colorSpace, descriptorCpuHandle,
230230
descriptorGpuHandle, _descriptorSize, nullptr, nullptr);
231-
231+
if (FAILED(hr)) {
232+
Logger::Get().ComError("CatmullRomEffectDrawer::OnColorInfoChanged 失败", hr);
233+
return hr;
234+
}
235+
232236
return S_OK;
233237
}
234238

src/Magpie.Core/FrameProducer.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,9 @@ void FrameProducer::OnColorInfoChangedAsync(
161161
return;
162162
}
163163

164-
_frameRingBuffer.UpdateResources(outputResources);
164+
if (!outputResources.empty()) {
165+
_frameRingBuffer.UpdateResources(outputResources);
166+
}
165167
}
166168

167169
// 等待新帧
@@ -218,11 +220,9 @@ void FrameProducer::_ProducerThreadProc(
218220
if (_Initialize(colorInfo, hMonSrc, srcRect, rendererSize, outputSize)) {
219221
// 同步 outputSize
220222
task.SetResult(true, std::memory_order_release);
221-
_state.store(ComponentState::NoError, std::memory_order_release);
222223
} else {
223224
Logger::Get().Error("_Initialize 失败");
224225
task.SetResult(false);
225-
_state.store(ComponentState::Error, std::memory_order_relaxed);
226226
return;
227227
}
228228

src/Magpie.Core/FrameProducer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class FrameProducer {
6868

6969
bool _CheckResult(HRESULT hr, std::string_view errorMsg) noexcept;
7070

71-
std::atomic<ComponentState> _state = ComponentState::Initializing;
71+
std::atomic<ComponentState> _state = ComponentState::NoError;
7272

7373
std::thread _producerThread;
7474
winrt::DispatcherQueue _dispatcher{ nullptr };

src/Magpie.Core/GraphicsCaptureFrameSource.cpp

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -327,18 +327,15 @@ HRESULT GraphicsCaptureFrameSource::CheckForNewFrame(bool& isNewFrameAvailable)
327327
return hr;
328328
}
329329

330-
if (_captureFrameResourceTable.empty()) {
331-
// 丢弃 Recreate 后收到的旧帧,WGC 内部没做同步
330+
#ifdef _DEBUG
331+
{
332332
D3D11_TEXTURE2D_DESC desc;
333333
d3d11Texture->GetDesc(&desc);
334334
const DXGI_FORMAT expectedFormat =
335335
_isScRGB ? DXGI_FORMAT_R16G16B16A16_FLOAT : DXGI_FORMAT_B8G8R8A8_UNORM;
336-
if (desc.Format != expectedFormat) {
337-
_newFrame = nullptr;
338-
isNewFrameAvailable = false;
339-
return S_OK;
340-
}
336+
assert(desc.Format == expectedFormat);
341337
}
338+
#endif
342339

343340
// 目前 WGC 帧池不会变化,因此可以缓存,需要采取保护措施防止内部实现变化
344341
auto it = std::find_if(
@@ -630,20 +627,16 @@ HRESULT GraphicsCaptureFrameSource::OnColorInfoChanged(const ColorInfo& colorInf
630627
return S_OK;
631628
}
632629

633-
_ReleaseCaptureFrames();
630+
// 重启捕获而不是 Recreate,这样可以立刻获得新帧
631+
_StopCapture();
634632

635-
try {
636-
winrt::DirectXPixelFormat format = _isScRGB ? winrt::DirectXPixelFormat::R16G16B16A16Float :
637-
winrt::DirectXPixelFormat::B8G8R8A8UIntNormalized;
638-
_captureFramePool.Recreate(_wrappedDevice, format, CalcCaptureFrameCount(),
639-
{ (int)_frameBox.right, (int)_frameBox.bottom });
640-
} catch (const winrt::hresult_error& e) {
641-
Logger::Get().ComInfo(StrHelper::Concat("Direct3D11CaptureFramePool::Recreate 失败: ",
642-
StrHelper::UTF16ToUTF8(e.message())), e.code());
643-
return e.code();
633+
HRESULT hr = _StartCapture();
634+
if (FAILED(hr)) {
635+
Logger::Get().ComError("_StartCapture 失败", hr);
636+
return hr;
644637
}
645-
646-
HRESULT hr = _CreateDisplayDependentResources();
638+
639+
hr = _CreateDisplayDependentResources();
647640
if (FAILED(hr)) {
648641
Logger::Get().ComError("_CreateDisplayDependentResources 失败", hr);
649642
return hr;
@@ -1276,17 +1269,11 @@ void GraphicsCaptureFrameSource::_StopCapture() noexcept {
12761269
_captureFramePool.Close();
12771270
_captureFramePool = nullptr;
12781271

1279-
_ReleaseCaptureFrames();
1280-
}
1281-
1282-
void GraphicsCaptureFrameSource::_ReleaseCaptureFrames() noexcept {
1272+
// 捕获已结束,可以安全操作 _latestFrame
12831273
{
1284-
winrt::Direct3D11CaptureFrame frame{ nullptr };
1285-
{
1286-
auto lk = _latestFrameLock.lock_exclusive();
1287-
frame = std::move(_latestFrame);
1288-
_latestFrameDirtyRects.clear();
1289-
}
1274+
auto lk = _latestFrameLock.lock_exclusive();
1275+
_latestFrame = nullptr;
1276+
_latestFrameDirtyRects.clear();
12901277
}
12911278

12921279
_captureFrameResourceTable.clear();

src/Magpie.Core/GraphicsCaptureFrameSource.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,6 @@ class GraphicsCaptureFrameSource {
6969

7070
void _StopCapture() noexcept;
7171

72-
void _ReleaseCaptureFrames() noexcept;
73-
7472
GraphicsContext* _graphicsContext = nullptr;
7573

7674
std::atomic<DWORD> _producerThreadId;
@@ -92,6 +90,8 @@ class GraphicsCaptureFrameSource {
9290
uint64_t _curCrossAdapterFenceValue = 0;
9391

9492
wil::srwlock _latestFrameLock;
93+
// 不要在持有 _latestFrameLock 时释放 _latestFrame 或调用其中的方法,和 WGC 内部的
94+
// 同步机制冲突。如果此时_Direct3D11CaptureFramePool_FrameArrived 正在执行会死锁。
9595
winrt::Windows::Graphics::Capture::Direct3D11CaptureFrame _latestFrame{ nullptr };
9696
SmallVector<Rect> _latestFrameDirtyRects;
9797

src/Magpie.Core/pch.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ static constexpr uint32_t MAX_CAPTURE_DIRTY_RECT_COUNT = 4;
7171
static constexpr uint32_t DUP_FRAME_DISPATCH_BLOCK_SIZE = 16;
7272

7373
enum class ComponentState {
74-
Initializing,
7574
NoError,
7675
DeviceLost,
7776
Error

0 commit comments

Comments
 (0)