@@ -96,6 +96,11 @@ ScalingError Renderer2::Initialize(
9696 _frameProducer.InitializeAsync (
9797 _graphicsContext, _colorInfo, hMonitor, srcRect, size, outputSize, task);
9898
99+ if (!_cursorDrawer.Initialize (_graphicsContext)) {
100+ Logger::Get ().Error (" CursorDrawer2::Initialize 失败" );
101+ return ScalingError::ScalingFailedGeneral;
102+ }
103+
99104 _presenter = std::make_unique<SwapChainPresenter>();
100105 if (!_presenter->Initialize (_graphicsContext, hwndAttach, size, _colorInfo)) {
101106 Logger::Get ().Error (" SwapChainPresenter::Initialize 失败" );
@@ -172,6 +177,11 @@ void Renderer2::OnResized(Size size) noexcept {
172177 return ;
173178 }
174179
180+ // 确保消费者不再使用环形缓冲区
181+ if (!_CheckResult (_graphicsContext.WaitForGpu (), " GraphicsContext::WaitForGpu 失败" )) {
182+ return ;
183+ }
184+
175185 Size outputSize;
176186 SimpleTask<HRESULT> task;
177187 _frameProducer.OnResizedAsync (size, outputSize, task);
@@ -186,8 +196,6 @@ void Renderer2::OnResized(Size size) noexcept {
186196 }
187197
188198 _UpdateOutputRect (outputSize);
189-
190- _CheckResult (_RenderImpl (true ), " _RenderImpl 失败" );
191199}
192200
193201void Renderer2::OnMsgDisplayChanged () noexcept {
@@ -339,22 +347,29 @@ HRESULT Renderer2::_UpdateColorSpace() noexcept {
339347 return S_OK;
340348 }
341349
350+ // 确保消费者不再使用环形缓冲区
351+ HRESULT hr = _graphicsContext.WaitForGpu ();
352+ if (FAILED (hr)) {
353+ Logger::Get ().ComError (" GraphicsContext::WaitForGpu 失败" , hr);
354+ return hr;
355+ }
356+
342357 SimpleTask<HRESULT> task;
343358 _frameProducer.OnColorInfoChangedAsync (_colorInfo, task);
344359
345- HRESULT hr = _presenter->OnColorInfoChanged (_colorInfo);
360+ hr = _presenter->OnColorInfoChanged (_colorInfo);
346361 if (FAILED (hr)) {
347362 Logger::Get ().ComError (" SwapChainPresenter::OnColorInfoChanged 失败" , hr);
348363 return hr;
349364 }
350365
351366 hr = task.GetResult ();
352- if (!_CheckResult (hr, " FrameProducer::OnColorInfoChangedAsync 失败" )) {
367+ if (FAILED (hr)) {
368+ Logger::Get ().ComError (" FrameProducer::OnColorInfoChangedAsync 失败" , hr);
353369 return hr;
354370 }
355371
356- _CheckResult (_RenderImpl (true ), " _RenderImpl 失败" );
357-
372+ ScalingWindow::Get ().Render ();
358373 return S_OK;
359374}
360375
@@ -383,41 +398,77 @@ HRESULT Renderer2::_RenderImpl(bool waitForGpu) noexcept {
383398
384399 ID3D12GraphicsCommandList* commandList = _graphicsContext.GetCommandList ();
385400
386- if (const Size size = _presenter->GetSize (); _outputRect == RECT{ 0 ,0 ,(LONG)size.width ,(LONG)size.height }) {
401+ {
402+ CD3DX12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition (
403+ frameTex, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_COPY_DEST, 0 );
404+ commandList->ResourceBarrier (1 , &barrier);
405+ }
406+
407+ if (Size size = _presenter->GetSize (); _outputRect == Rect{ 0 ,0 ,size.width ,size.height }) {
408+ commandList->CopyResource (frameTex, curBuffer);
409+
387410 {
388411 CD3DX12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition (
389- frameTex, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_COPY_DEST , 0 );
412+ frameTex, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PRESENT , 0 );
390413 commandList->ResourceBarrier (1 , &barrier);
391414 }
392-
393- commandList->CopyResource (frameTex, curBuffer);
394415 } else {
416+ CD3DX12_TEXTURE_COPY_LOCATION src (curBuffer, 0 );
417+ CD3DX12_TEXTURE_COPY_LOCATION dest (frameTex, 0 );
418+ commandList->CopyTextureRegion (&dest, _outputRect.left , _outputRect.top , 0 , &src, nullptr );
419+
395420 {
396421 D3D12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition (
397- frameTex, D3D12_RESOURCE_STATE_PRESENT , D3D12_RESOURCE_STATE_RENDER_TARGET, 0 );
422+ frameTex, D3D12_RESOURCE_STATE_COPY_DEST , D3D12_RESOURCE_STATE_RENDER_TARGET, 0 );
398423 commandList->ResourceBarrier (1 , &barrier);
399424 }
400425
401426 // 存在黑边时应填充背景。使用交换链呈现时需要这个操作,因为我们指定了
402427 // DXGI_SWAP_EFFECT_FLIP_DISCARD,同时也是为了和 RTSS 兼容。
403- static constexpr FLOAT BLACK[4 ] = { 0 .0f ,0 .0f ,0 .0f ,1 .0f };
404- commandList->ClearRenderTargetView (rtvHandle, BLACK, 0 , nullptr );
428+ {
429+ SmallVector<D3D12_RECT, 4 > rects;
430+ if (_outputRect.left > 0 ) {
431+ rects.push_back ({
432+ 0 ,
433+ 0 ,
434+ (LONG)_outputRect.left ,
435+ (LONG)size.height
436+ });
437+ }
438+ if (_outputRect.top > 0 ) {
439+ rects.push_back ({
440+ (LONG)_outputRect.left ,
441+ 0 ,
442+ (LONG)_outputRect.right ,
443+ (LONG)_outputRect.top
444+ });
445+ }
446+ if (_outputRect.right < size.width ) {
447+ rects.push_back ({
448+ (LONG)_outputRect.right ,
449+ 0 ,
450+ (LONG)size.width ,
451+ (LONG)size.height
452+ });
453+ }
454+ if (_outputRect.bottom < size.height ) {
455+ rects.push_back ({
456+ (LONG)_outputRect.left ,
457+ (LONG)_outputRect.bottom ,
458+ (LONG)_outputRect.right ,
459+ (LONG)size.height
460+ });
461+ }
462+
463+ static constexpr FLOAT BLACK[4 ] = { 0 .0f ,0 .0f ,0 .0f ,1 .0f };
464+ commandList->ClearRenderTargetView (rtvHandle, BLACK, (UINT)rects.size (), rects.data ());
465+ }
405466
406467 {
407468 CD3DX12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition (
408- frameTex, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_DEST , 0 );
469+ frameTex, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT , 0 );
409470 commandList->ResourceBarrier (1 , &barrier);
410471 }
411-
412- CD3DX12_TEXTURE_COPY_LOCATION src (curBuffer, 0 );
413- CD3DX12_TEXTURE_COPY_LOCATION dest (frameTex, 0 );
414- commandList->CopyTextureRegion (&dest, _outputRect.left , _outputRect.top , 0 , &src, nullptr );
415- }
416-
417- {
418- CD3DX12_RESOURCE_BARRIER barrier = CD3DX12_RESOURCE_BARRIER::Transition (
419- frameTex, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PRESENT, 0 );
420- commandList->ResourceBarrier (1 , &barrier);
421472 }
422473
423474 hr = commandList->Close ();
@@ -480,8 +531,8 @@ void Renderer2::_UpdateOutputRect(Size outputSize) noexcept {
480531 _outputRect.bottom = rendererSize.height ;
481532 }
482533
483- assert (_outputRect.left + (LONG) outputSize.width == _outputRect.right );
484- assert (_outputRect.top + (LONG) outputSize.height == _outputRect.bottom );
534+ assert (_outputRect.left + outputSize.width == _outputRect.right );
535+ assert (_outputRect.top + outputSize.height == _outputRect.bottom );
485536}
486537
487538bool Renderer2::_CheckResult (bool success, std::string_view errorMsg) noexcept {
0 commit comments