Skip to content

Commit

Permalink
OpenVRRenderLoop needs to recover from WAIT_ABANDONED
Browse files Browse the repository at this point in the history
If IDXGIKeyedMutex::AcquireSync fails, it may be non-recoverable, and we
need to create a new texture/GpuMemoryBuffer.

Change-Id: Idd90a6ad38505736606fc488705ce63c45ef6d93
Reviewed-on: https://chromium-review.googlesource.com/794023
Commit-Queue: Bill Orr <billorr@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Reviewed-by: Michael Thiessen <mthiesse@chromium.org>
Reviewed-by: Klaus Weidner <klausw@chromium.org>
Cr-Commit-Position: refs/heads/master@{#520000}
  • Loading branch information
Bill Orr authored and Commit Bot committed Nov 29, 2017
1 parent 64e1228 commit add2819
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 10 deletions.
2 changes: 1 addition & 1 deletion chrome/browser/android/vr_shell/vr_shell_gl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ void VrShellGl::SubmitFrame(int16_t frame_index,
}
// Always notify the client that we're done with the mailbox even
// if we haven't drawn it, so that it's eligible for destruction.
submit_client_->OnSubmitFrameTransferred();
submit_client_->OnSubmitFrameTransferred(true);
if (!swapped) {
// We dropped without drawing, report this as completed rendering
// now to unblock the client. We're not going to receive it in
Expand Down
11 changes: 6 additions & 5 deletions device/vr/openvr/openvr_render_loop.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ void OpenVRRenderLoop::SubmitFrameWithTextureHandle(
texture_helper_.SetSourceTexture(
base::win::ScopedHandle(reinterpret_cast<HANDLE>(platform_handle.value)));
texture_helper_.AllocateBackBuffer();
if (texture_helper_.CopyTextureToBackBuffer(true)) {
bool copy_successful = texture_helper_.CopyTextureToBackBuffer(true);
if (copy_successful) {
vr::Texture_t texture;
texture.handle = texture_helper_.GetBackbuffer().Get();
texture.eType = vr::TextureType_DirectX;
Expand All @@ -72,11 +73,11 @@ void OpenVRRenderLoop::SubmitFrameWithTextureHandle(
return;
}
vr_compositor_->PostPresentHandoff();

// Tell WebVR that we are done with the texture.
submit_client_->OnSubmitFrameTransferred();
submit_client_->OnSubmitFrameRendered();
}

// Tell WebVR that we are done with the texture.
submit_client_->OnSubmitFrameTransferred(copy_successful);
submit_client_->OnSubmitFrameRendered();
#endif
}

Expand Down
21 changes: 20 additions & 1 deletion device/vr/vr_service.mojom
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,27 @@ interface VRServiceClient {
VRDisplayInfo display_info);
};

// After submitting a frame, the VRPresentationProvider will notify the client
// about several stages of the render pipeline. This allows pipelining
// efficiency. Following VRPresentationProvider::Submit*, the submitted frame
// will be transferred (read from, perhaps copied to another texture), and then
// rendered (submitted to the underlying VR API).
// The client lives in the render process, implemented by VRDisplay.
interface VRSubmitFrameClient {
OnSubmitFrameTransferred();
// The VRPresentationProvider calls this to indicate that the submitted frame
// has been transferred, so the backing data (mailbox or GpuMemoryBuffer) can
// be reused or discarded. Note that this is a convenience/optimization
// feature, not a security feature - if a site discards the data early we may
// drop a frame, but nothing will otherwise misbehave.
// When the frame wasn't successfully transferred, the client should create a
// new mailbox/GpuMemoryBuffer rather than reusing an existing one to recover
// for subsequent frames.
OnSubmitFrameTransferred(bool success);

// The VRPresentationProvider calls this after the frame was handed off to the
// underlying VR API. This allows some pipelining of CPU/GPU work, while
// delaying expensive tasks for a subsequent frame until the current frame has
// completed.
OnSubmitFrameRendered();
};

Expand Down
5 changes: 3 additions & 2 deletions third_party/WebKit/Source/modules/vr/VRDisplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,7 @@ void VRDisplay::submitFrame() {
if (present_image_needs_copy_) {
#if defined(OS_WIN)
TRACE_EVENT0("gpu", "VRDisplay::CopyImage");
if (!frame_copier_) {
if (!frame_copier_ || !last_transfer_succeeded_) {
frame_copier_ = std::make_unique<GpuMemoryBufferImageCopy>(context_gl_);
}
auto gpu_memory_buffer = frame_copier_->CopyImage(image_ref.get());
Expand Down Expand Up @@ -784,9 +784,10 @@ void VRDisplay::submitFrame() {
rendering_context_->MarkCompositedAndClearBackbufferIfNeeded();
}

void VRDisplay::OnSubmitFrameTransferred() {
void VRDisplay::OnSubmitFrameTransferred(bool success) {
DVLOG(3) << __FUNCTION__;
pending_submit_frame_ = false;
last_transfer_succeeded_ = success;
}

void VRDisplay::OnSubmitFrameRendered() {
Expand Down
3 changes: 2 additions & 1 deletion third_party/WebKit/Source/modules/vr/VRDisplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class VRDisplay final : public EventTargetWithInlineData,
void OnPresentChange();

// VRSubmitFrameClient
void OnSubmitFrameTransferred() override;
void OnSubmitFrameTransferred(bool success) override;
void OnSubmitFrameRendered() override;

// VRDisplayClient
Expand Down Expand Up @@ -215,6 +215,7 @@ class VRDisplay final : public EventTargetWithInlineData,
bool pending_previous_frame_render_ = false;
bool pending_submit_frame_ = false;
bool pending_present_request_ = false;
bool last_transfer_succeeded_ = false;

device::mojom::blink::VRMagicWindowProviderPtr magic_window_provider_;
device::mojom::blink::VRDisplayHostPtr display_;
Expand Down

0 comments on commit add2819

Please sign in to comment.