[M150] [WGC] Fix frame size synchronization Original change's description: > [WGC] Fix frame size synchronization > > Fixes a scenario where the mapped_texture_ and frame_pool_ sizes of the > WGC capturer could get out of sync and potentially bypass their > reconciliation on the following frame. > > Fixed: chromium:517727318 > Change-Id: Ie4e951bbdf41491200b7ba1289f85e4c02bc22d1 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/476860 > Commit-Queue: Mark Foltz <mfoltz@chromium.org> > Auto-Submit: Alexander Cooper <alcooper@chromium.org> > Reviewed-by: Mark Foltz <mfoltz@chromium.org> > Cr-Commit-Position: refs/heads/main@{#47898} (cherry picked from commit b5cf1fa607113788cf894d5b6895c72fba1d9254) Bug: chromium:520652713,chromium:517727318 Change-Id: Ie4e951bbdf41491200b7ba1289f85e4c02bc22d1 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/479881 Commit-Queue: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com> Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com> Auto-Submit: Chrome Cherry Picker <chrome-cherry-picker@chops-service-accounts.iam.gserviceaccount.com> Cr-Commit-Position: refs/branch-heads/7871@{#1} Cr-Branched-From: b1dde843dc4388c62a66f8ca903e795463b04075-refs/heads/main@{#47863}
diff --git a/modules/desktop_capture/win/wgc_capture_session.cc b/modules/desktop_capture/win/wgc_capture_session.cc index c7eaf54..9a887d7 100644 --- a/modules/desktop_capture/win/wgc_capture_session.cc +++ b/modules/desktop_capture/win/wgc_capture_session.cc
@@ -564,14 +564,6 @@ return hr; } - if (!mapped_texture_) { - hr = CreateMappedTexture(texture_2D); - if (FAILED(hr)) { - RecordGetFrameResult(GetFrameResult::kCreateMappedTextureFailed); - return hr; - } - } - // We need to copy `texture_2D` into `mapped_texture_` as the latter has the // D3D11_CPU_ACCESS_READ flag set, which lets us access the image data. // Otherwise it would only be readable by the GPU. @@ -588,17 +580,28 @@ // If the size changed, we must resize `mapped_texture_` and `frame_pool_` to // fit the new size. This must be done before `CopySubresourceRegion` so that // the textures are the same size. - if (SizeHasChanged(new_size, size_)) { + const bool needs_resize = SizeHasChanged(new_size, size_); + + if (!mapped_texture_ || needs_resize) { hr = CreateMappedTexture(texture_2D, new_size.Width, new_size.Height); if (FAILED(hr)) { - RecordGetFrameResult(GetFrameResult::kResizeMappedTextureFailed); + RecordGetFrameResult(GetFrameResult::kCreateMappedTextureFailed); return hr; } + } + if (needs_resize) { hr = frame_pool_->Recreate(direct3d_device_.Get(), kPixelFormat, num_buffers(), new_size); if (FAILED(hr)) { RecordGetFrameResult(GetFrameResult::kRecreateFramePoolFailed); + // On failure, `frame_pool_` remains at `size_`. Reset `mapped_texture_` + // because `mapped_texture_` and `frame_pool_` are now at inconsistent + // sizes. Clearing it forces a consistent recreation on the next frame. + // Note that it's not sufficient to simply leave `mapped_texture_` at it's + // current size, because if the window were to be resized back to `size_`, + // then we would erroneously think we don't need to re-create the texture. + mapped_texture_.Reset(); return hr; } } @@ -713,7 +716,7 @@ const int width_in_bytes = current_frame->size().width() * DesktopFrame::kBytesPerPixel; RTC_DCHECK_GE(current_frame->stride(), width_in_bytes); - RTC_DCHECK_GE(map_info.RowPitch, width_in_bytes); + RTC_CHECK_GE(map_info.RowPitch, width_in_bytes); const int middle_pixel_offset = (image_width / 2) * DesktopFrame::kBytesPerPixel; for (int i = 0; i < image_height; i++) {