Skip to content

Commit df05e9e

Browse files
committed
perf: 提高改变大小和色域的性能
1 parent a197c47 commit df05e9e

File tree

7 files changed

+183
-142
lines changed

7 files changed

+183
-142
lines changed

src/Magpie.Core/FrameProducer.cpp

Lines changed: 113 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -33,33 +33,27 @@ FrameProducer::~FrameProducer() noexcept {
3333

3434
void FrameProducer::InitializeAsync(
3535
const GraphicsContext& graphicsContext,
36+
const ColorInfo& colorInfo,
37+
HMONITOR hMonSrc,
3638
const RECT& srcRect,
3739
Size rendererSize,
38-
HMONITOR hMonSrc,
39-
const ColorInfo& colorInfo
40+
Size& outputSize,
41+
SimpleTask<bool>& task
4042
) noexcept {
4143
_graphicsContext.CopyDevice(graphicsContext);
4244

4345
_producerThread = std::thread(
4446
&FrameProducer::_ProducerThreadProc,
4547
this,
48+
colorInfo,
49+
hMonSrc,
4650
srcRect,
4751
rendererSize,
48-
hMonSrc,
49-
colorInfo
52+
std::ref(outputSize),
53+
std::ref(task)
5054
);
5155
}
5256

53-
bool FrameProducer::WaitForInitialize(Size& outputSize) const noexcept {
54-
_state.wait(ComponentState::Initializing, std::memory_order_relaxed);
55-
if (_state.load(std::memory_order_acquire) == ComponentState::NoError) {
56-
outputSize = _initalOutputSize;
57-
return true;
58-
} else {
59-
return false;
60-
}
61-
}
62-
6357
ComponentState FrameProducer::GetState() const noexcept {
6458
return _state.load(std::memory_order_relaxed);
6559
}
@@ -79,127 +73,123 @@ HRESULT FrameProducer::ConsumerEndFrame(
7973
return _frameRingBuffer.ConsumerEndFrame(commandQueue, fenceValueToSignal);
8074
}
8175

82-
HRESULT FrameProducer::OnResized(Size rendererSize, Size& outputSize) noexcept {
83-
HRESULT hr = S_OK;
84-
std::atomic<bool> done = false;
85-
76+
void FrameProducer::OnResizedAsync(
77+
Size rendererSize,
78+
Size& outputSize,
79+
SimpleTask<HRESULT>& task
80+
) noexcept {
8681
_dispatcher.TryEnqueue([&] {
87-
[&] {
88-
ComponentState state = _state.load(std::memory_order_relaxed);
89-
if (state != ComponentState::NoError) {
90-
hr = state == ComponentState::DeviceLost ? DXGI_ERROR_DEVICE_REMOVED : E_FAIL;
91-
return;
92-
}
82+
HRESULT hr = S_OK;
83+
auto se = wil::scope_exit([&] {
84+
// 同步 outputSize
85+
task.SetResult(hr, std::memory_order_release);
86+
});
87+
88+
ComponentState state = _state.load(std::memory_order_relaxed);
89+
if (state != ComponentState::NoError) {
90+
hr = state == ComponentState::DeviceLost ? DXGI_ERROR_DEVICE_REMOVED : E_FAIL;
91+
return;
92+
}
9393

94-
hr = _graphicsContext.WaitForGpu();
95-
if (!_CheckResult(hr, "GraphicsContext::WaitForGpu 失败")) {
96-
return;
97-
}
94+
hr = _graphicsContext.WaitForGpu();
95+
if (!_CheckResult(hr, "GraphicsContext::WaitForGpu 失败")) {
96+
return;
97+
}
9898

99-
SmallVector<winrt::com_ptr<ID3D12Resource>, 4> outputResources;
100-
hr = _effectsDrawer.OnResized(rendererSize, outputResources);
101-
if (!_CheckResult(hr, "EffectsDrawer::OnResized 失败")) {
102-
return;
103-
}
99+
SmallVector<winrt::com_ptr<ID3D12Resource>, 4> outputResources;
100+
hr = _effectsDrawer.OnResized(rendererSize, outputResources);
101+
if (!_CheckResult(hr, "EffectsDrawer::OnResized 失败")) {
102+
return;
103+
}
104104

105-
outputSize = _effectsDrawer.GetOutputSize();
105+
outputSize = _effectsDrawer.GetOutputSize();
106106

107-
_frameRingBuffer.UpdateResources(outputResources);
107+
_frameRingBuffer.UpdateResources(outputResources);
108108

109-
hr = _Render();
110-
if (!_CheckResult(hr, "_Render 失败")) {
111-
return;
112-
}
109+
hr = _Render();
110+
if (!_CheckResult(hr, "_Render 失败")) {
111+
return;
112+
}
113113

114-
// 等待渲染完成
115-
hr = _graphicsContext.WaitForGpu();
116-
if (!_CheckResult(hr, "GraphicsContext::WaitForGpu 失败")) {
117-
return;
118-
}
119-
}();
120-
121-
done.store(true, std::memory_order_release);
122-
done.notify_one();
114+
// 等待渲染完成
115+
hr = _graphicsContext.WaitForGpu();
116+
if (!_CheckResult(hr, "GraphicsContext::WaitForGpu 失败")) {
117+
return;
118+
}
123119
});
124-
125-
done.wait(false, std::memory_order_acquire);
126-
return hr;
127120
}
128121

129-
HRESULT FrameProducer::OnColorInfoChanged(const ColorInfo& colorInfo) noexcept {
130-
HRESULT hr = S_OK;
131-
std::atomic<bool> done = false;
132-
122+
void FrameProducer::OnColorInfoChangedAsync(
123+
const ColorInfo& colorInfo,
124+
SimpleTask<HRESULT>& task
125+
) noexcept {
133126
_dispatcher.TryEnqueue([&] {
134-
[&] {
135-
ComponentState state = _state.load(std::memory_order_relaxed);
136-
if (state != ComponentState::NoError) {
137-
hr = state == ComponentState::DeviceLost ? DXGI_ERROR_DEVICE_REMOVED : E_FAIL;
138-
return;
139-
}
140-
141-
hr = _graphicsContext.WaitForGpu();
142-
if (!_CheckResult(hr, "GraphicsContext::WaitForGpu 失败")) {
143-
return;
144-
}
145-
146-
hr = _frameSource->OnColorInfoChanged(colorInfo);
147-
if (!_CheckResult(hr, "GraphicsCaptureFrameSource::OnColorInfoChanged 失败")) {
148-
return;
149-
}
150-
151-
{
152-
const uint32_t maxInFlightFrameCount =
153-
ScalingWindow::Get().Options().maxProducerInFlightFrames;
127+
HRESULT hr = S_OK;
128+
auto se = wil::scope_exit([&] {
129+
task.SetResult(hr);
130+
});
131+
132+
ComponentState state = _state.load(std::memory_order_relaxed);
133+
if (state != ComponentState::NoError) {
134+
hr = state == ComponentState::DeviceLost ? DXGI_ERROR_DEVICE_REMOVED : E_FAIL;
135+
return;
136+
}
154137

155-
SmallVector<ID3D12Resource*, 3> inputResources;
156-
for (uint32_t i = 0; i < maxInFlightFrameCount; ++i) {
157-
inputResources.push_back(_frameSource->GetOutput(i));
158-
}
138+
hr = _graphicsContext.WaitForGpu();
139+
if (!_CheckResult(hr, "GraphicsContext::WaitForGpu 失败")) {
140+
return;
141+
}
159142

160-
SmallVector<winrt::com_ptr<ID3D12Resource>, 4> outputResources;
143+
hr = _frameSource->OnColorInfoChanged(colorInfo);
144+
if (!_CheckResult(hr, "GraphicsCaptureFrameSource::OnColorInfoChanged 失败")) {
145+
return;
146+
}
161147

162-
hr = _effectsDrawer.OnColorInfoChanged(colorInfo, inputResources, outputResources);
163-
if (!_CheckResult(hr, "EffectsDrawer::OnColorInfoChanged 失败")) {
164-
return;
165-
}
148+
{
149+
const uint32_t maxInFlightFrameCount =
150+
ScalingWindow::Get().Options().maxProducerInFlightFrames;
166151

167-
_frameRingBuffer.UpdateResources(outputResources);
152+
SmallVector<ID3D12Resource*, 3> inputResources;
153+
for (uint32_t i = 0; i < maxInFlightFrameCount; ++i) {
154+
inputResources.push_back(_frameSource->GetOutput(i));
168155
}
169156

170-
// 等待新帧
171-
while (true) {
172-
bool isNewFrameAvailable;
173-
hr = _frameSource->CheckForNewFrame(isNewFrameAvailable);
174-
if (!_CheckResult(hr, "GraphicsCaptureFrameSource::CheckForNewFrame 失败")) {
175-
return;
176-
}
157+
SmallVector<winrt::com_ptr<ID3D12Resource>, 4> outputResources;
177158

178-
if (isNewFrameAvailable) {
179-
break;
180-
} else {
181-
WaitMessage();
182-
}
159+
hr = _effectsDrawer.OnColorInfoChanged(colorInfo, inputResources, outputResources);
160+
if (!_CheckResult(hr, "EffectsDrawer::OnColorInfoChanged 失败")) {
161+
return;
183162
}
184163

185-
hr = _Render();
186-
if (!_CheckResult(hr, "_Render 失败")) {
164+
_frameRingBuffer.UpdateResources(outputResources);
165+
}
166+
167+
// 等待新帧
168+
while (true) {
169+
bool isNewFrameAvailable;
170+
hr = _frameSource->CheckForNewFrame(isNewFrameAvailable);
171+
if (!_CheckResult(hr, "GraphicsCaptureFrameSource::CheckForNewFrame 失败")) {
187172
return;
188173
}
189174

190-
// 等待渲染完成
191-
hr = _graphicsContext.WaitForGpu();
192-
if (!_CheckResult(hr, "GraphicsContext::WaitForGpu 失败")) {
193-
return;
175+
if (isNewFrameAvailable) {
176+
break;
177+
} else {
178+
WaitMessage();
194179
}
195-
}();
196-
197-
done.store(true, std::memory_order_release);
198-
done.notify_one();
199-
});
180+
}
200181

201-
done.wait(false, std::memory_order_acquire);
202-
return hr;
182+
hr = _Render();
183+
if (!_CheckResult(hr, "_Render 失败")) {
184+
return;
185+
}
186+
187+
// 等待渲染完成
188+
hr = _graphicsContext.WaitForGpu();
189+
if (!_CheckResult(hr, "GraphicsContext::WaitForGpu 失败")) {
190+
return;
191+
}
192+
});
203193
}
204194

205195
void FrameProducer::OnCursorVisibilityChanged(bool isVisible, bool onDestory) noexcept {
@@ -214,21 +204,25 @@ void FrameProducer::OnCursorVisibilityChanged(bool isVisible, bool onDestory) no
214204
}
215205

216206
void FrameProducer::_ProducerThreadProc(
207+
const ColorInfo& colorInfo,
208+
HMONITOR hMonSrc,
217209
RECT srcRect,
218210
Size rendererSize,
219-
HMONITOR hMonSrc,
220-
const ColorInfo& colorInfo
211+
Size& outputSize,
212+
SimpleTask<bool>& task
221213
) noexcept {
222214
#ifdef _DEBUG
223215
SetThreadDescription(GetCurrentThread(), L"Magpie-缩放生产者线程");
224216
#endif
225217

226-
if (_Initialize(srcRect, rendererSize, hMonSrc, colorInfo)) {
218+
if (_Initialize(colorInfo, hMonSrc, srcRect, rendererSize, outputSize)) {
219+
// 同步 outputSize
220+
task.SetResult(true, std::memory_order_release);
227221
_state.store(ComponentState::NoError, std::memory_order_release);
228-
_state.notify_one();
229222
} else {
223+
Logger::Get().Error("_Initialize 失败");
224+
task.SetResult(false);
230225
_state.store(ComponentState::Error, std::memory_order_relaxed);
231-
_state.notify_one();
232226
return;
233227
}
234228

@@ -311,10 +305,11 @@ void FrameProducer::_ProducerThreadProc(
311305
}
312306

313307
bool FrameProducer::_Initialize(
308+
const ColorInfo& colorInfo,
309+
HMONITOR hMonSrc,
314310
const RECT& srcRect,
315311
Size rendererSize,
316-
HMONITOR hMonSrc,
317-
const ColorInfo& colorInfo
312+
Size& outputSize
318313
) noexcept {
319314
winrt::init_apartment(winrt::apartment_type::single_threaded);
320315

@@ -404,7 +399,7 @@ bool FrameProducer::_Initialize(
404399
return false;
405400
}
406401

407-
_initalOutputSize = _effectsDrawer.GetOutputSize();
402+
outputSize = _effectsDrawer.GetOutputSize();
408403

409404
if (!_frameRingBuffer.Initialize(_graphicsContext, outputResources)) {
410405
Logger::Get().Error("初始化 FrameRingBuffer 失败");

src/Magpie.Core/FrameProducer.h

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "EffectsDrawer.h"
44
#include "FrameRingBuffer.h"
55
#include "StepTimer.h"
6+
#include "SimpleTask.h"
67

78
namespace Magpie {
89

@@ -18,14 +19,14 @@ class FrameProducer {
1819

1920
void InitializeAsync(
2021
const GraphicsContext& graphicsContext,
22+
const ColorInfo& colorInfo,
23+
HMONITOR hMonSrc,
2124
const RECT& srcRect,
2225
Size rendererSize,
23-
HMONITOR hMonSrc,
24-
const ColorInfo& colorInfo
26+
Size& outputSize,
27+
SimpleTask<bool>& task
2528
) noexcept;
2629

27-
bool WaitForInitialize(Size& outputSize) const noexcept;
28-
2930
ComponentState GetState() const noexcept;
3031

3132
uint64_t GetLatestFrameNumber() const noexcept;
@@ -37,25 +38,28 @@ class FrameProducer {
3738
UINT64 fenceValueToSignal
3839
) const noexcept;
3940

40-
HRESULT OnResized(Size rendererSize, Size& outputSize) noexcept;
41+
void OnResizedAsync(Size rendererSize, Size& outputSize, SimpleTask<HRESULT>& task) noexcept;
4142

42-
HRESULT OnColorInfoChanged(const ColorInfo& colorInfo) noexcept;
43+
void OnColorInfoChangedAsync(const ColorInfo& colorInfo, SimpleTask<HRESULT>& task) noexcept;
4344

4445
void OnCursorVisibilityChanged(bool isVisible, bool onDestory) noexcept;
4546

4647
private:
4748
void _ProducerThreadProc(
49+
const ColorInfo& colorInfo,
50+
HMONITOR hMonSrc,
4851
RECT srcRect,
4952
Size rendererSize,
50-
HMONITOR hMonSrc,
51-
const ColorInfo& colorInfo
53+
Size& outputSize,
54+
SimpleTask<bool>& task
5255
) noexcept;
5356

5457
bool _Initialize(
58+
const ColorInfo& colorInfo,
59+
HMONITOR hMonSrc,
5560
const RECT& srcRect,
5661
Size rendererSize,
57-
HMONITOR hMonSrc,
58-
const ColorInfo& colorInfo
62+
Size& outputSize
5963
) noexcept;
6064

6165
HRESULT _Render() noexcept;
@@ -76,8 +80,6 @@ class FrameProducer {
7680
StepTimer _stepTimer;
7781
std::unique_ptr<GraphicsCaptureFrameSource> _frameSource;
7882
EffectsDrawer _effectsDrawer;
79-
80-
Size _initalOutputSize{};
8183
};
8284

8385
}

0 commit comments

Comments
 (0)