Commit fd7c4f20 authored by Bill Orr's avatar Bill Orr Committed by Commit Bot

Fix WebXR and WebVR viewport scaling on desktop

compositor_base was confusing top/bottom of image with DX vs. GL
coordinates.

Mirroring UVs were making a similar error, measuring from top instead of
bottom.

This change makes WebVR and WebXR behave similarly on desktop and
Android.

Bug: 949594
Change-Id: Ie4ead47d6582fcd3578d037a30380ec1f2e9f44d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1566424Reviewed-by: default avatarBrandon Jones <bajones@chromium.org>
Commit-Queue: Bill Orr <billorr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#650555}
parent 8a460e0f
...@@ -168,6 +168,13 @@ void XRCompositorCommon::UpdateLayerBounds(int16_t frame_id, ...@@ -168,6 +168,13 @@ void XRCompositorCommon::UpdateLayerBounds(int16_t frame_id,
// merge with vr_shell_gl eventually. // merge with vr_shell_gl eventually.
left_webxr_bounds_ = left_bounds; left_webxr_bounds_ = left_bounds;
right_webxr_bounds_ = right_bounds; right_webxr_bounds_ = right_bounds;
// Swap top/bottom to account for differences between D3D and GL coordinates.
left_webxr_bounds_.set_y(
1 - (left_webxr_bounds_.y() + left_webxr_bounds_.height()));
right_webxr_bounds_.set_y(
1 - (right_webxr_bounds_.y() + right_webxr_bounds_.height()));
source_size_ = source_size; source_size_ = source_size;
OnLayerBoundsChanged(); OnLayerBoundsChanged();
......
...@@ -227,12 +227,10 @@ void XRWebGLLayer::UpdateViewports() { ...@@ -227,12 +227,10 @@ void XRWebGLLayer::UpdateViewports() {
// When mirroring make sure to also update the mirrored canvas UVs so it // When mirroring make sure to also update the mirrored canvas UVs so it
// only shows a single eye's data, cropped to display proportionally. // only shows a single eye's data, cropped to display proportionally.
if (session()->outputContext()) { if (session()->outputContext()) {
float left = 0; float source_pixels_left = left_viewport_->x();
float top = 0; float source_pixels_right = left_viewport_->x() + left_viewport_->width();
float right = static_cast<float>(left_viewport_->width()) / float source_pixels_bottom = left_viewport_->y();
static_cast<float>(framebuffer_width); float source_pixels_top = left_viewport_->y() + left_viewport_->height();
float bottom = static_cast<float>(left_viewport_->height()) /
static_cast<float>(framebuffer_height);
// Adjust the UVs so that the mirrored content always fills the canvas // Adjust the UVs so that the mirrored content always fills the canvas
// and is centered while staying proportional. // and is centered while staying proportional.
...@@ -242,23 +240,32 @@ void XRWebGLLayer::UpdateViewports() { ...@@ -242,23 +240,32 @@ void XRWebGLLayer::UpdateViewports() {
static_cast<float>(left_viewport_->height()); static_cast<float>(left_viewport_->height());
if (output_aspect > viewport_aspect) { if (output_aspect > viewport_aspect) {
float viewport_scale = bottom; // Output is wider than rendered image, scale to height and chop off top
output_aspect = viewport_aspect / output_aspect; // and bottom.
top = 0.5 - (output_aspect * 0.5); float cropped_image_height = left_viewport_->width() / output_aspect;
bottom = top + output_aspect; float crop_amount = (left_viewport_->height() - cropped_image_height);
top *= viewport_scale; source_pixels_top -= crop_amount / 2;
bottom *= viewport_scale; source_pixels_bottom += crop_amount / 2;
} else { } else {
float viewport_scale = right; // Output is taller relatively than rendered image, scale to width and
output_aspect = output_aspect / viewport_aspect; // chop of left and right.
left = 0.5 - (output_aspect * 0.5); float cropped_image_width = left_viewport_->height() * output_aspect;
right = left + output_aspect; float crop_amount = (left_viewport_->width() - cropped_image_width);
left *= viewport_scale; source_pixels_left += crop_amount / 2;
right *= viewport_scale; source_pixels_right -= crop_amount / 2;
} }
session()->outputContext()->SetUV(FloatPoint(left, top), float uv_left = source_pixels_left / framebuffer_width;
FloatPoint(right, bottom)); float uv_right = source_pixels_right / framebuffer_width;
float uv_top = source_pixels_top / framebuffer_height;
float uv_bottom = source_pixels_bottom / framebuffer_height;
// Finally, in UV space (0, 0) is top-left corner, so we need to flip.
uv_top = 1 - uv_top;
uv_bottom = 1 - uv_bottom;
session()->outputContext()->SetUV(FloatPoint(uv_left, uv_top),
FloatPoint(uv_right, uv_bottom));
} }
} else { } else {
left_viewport_ = MakeGarbageCollected<XRViewport>( left_viewport_ = MakeGarbageCollected<XRViewport>(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment