New issue
Advanced search Search tips

Issue 845742 link

Starred by 3 users

Issue metadata

Status: Assigned
Owner:
Components:
EstimatedDays: ----
NextAction: ----
OS: Windows
Pri: 2
Type: Bug
Proj-XR
Proj-XR-VR

Blocked on:
issue 756347

Blocking:
issue 773882
issue 841062



Sign in to add a comment

Too large of a canvas size can break webvr in chrome

Project Member Reported by billorr@chromium.org, May 23 2018

Issue description

If you change onVRDisplayPresentChange in THREEJS to something like

var renderWidth = eyeParameters.renderWidth * 1.5;
var renderHeight = eyeParameters.renderHeight * 1.5;


 
Status: Available (was: Untriaged)
bulk assinging windows-related vr bugs to myself.
Components: Internals>XR
Labels: VR-Desktop
Components: -Internals>XR Internals>XR>VR
Labels: -Pri-3 Pri-2
Owner: klausw@chromium.org
A scale factor of 1.5 was working fine for me, it's possible that a related issue was fixed by r576728 for  issue 835905 .

However, I can still reproduce the issue with very large render canvas sizes, for example:

https://webvr.info/samples/test-slow-render.html?heavyGpu=1&cubeScale=0.3&standardSize=1&renderScale=4

The left eye looks OK, the right eye view is truncated, with the right section of the display being plain black.

Issue seems to be a poorly-documented hardcoded 16 MiPixel canvas area limit:

https://cs.chromium.org/chromium/src/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc?l=1649&rcl=1db2b3a1989d8e728e07c8c4a1e2c8e917dd0cb9

  // Limit drawing buffer area to 4k*4k to avoid memory exhaustion. Width or
  // height may be larger than 4k as long as it's within the max viewport
  // dimensions and total area remains within the limit.
  // For example: 5120x2880 should be fine.
  const int kMaxArea = 4096 * 4096;
  int current_area = width * height;
  if (current_area > kMaxArea) {
    // If we've exceeded the area limit scale the buffer down, preserving
    // ascpect ratio, until it fits.
    float scale_factor =
        sqrtf(static_cast<float>(kMaxArea) / static_cast<float>(current_area));
    width = std::max(1, static_cast<int>(width * scale_factor));
    height = std::max(1, static_cast<int>(height * scale_factor));
  }

=> (with some extra logging added)

[INFO:webgl_rendering_context_base.cc(1655)] Reshape size=8192x4096
[INFO:webgl_rendering_context_base.cc(1663)] Reshape >kMaxArea, new size=5792x2896

FWIW, the result of the area-limit reshaping is inconsistent. It seems that the canvas keeps the user-requested size, while the drawing buffer uses a reduced size. For WebVR 1.1, various code locations still use the expected 8192x4096 size, including the gpu_memory_buffer_image_copy code and browser side, so the expected memory savings from the drawing buffer's size reduction don't fully work. It just breaks rendering due to the size mismatch resulting in a partially rendered image.
See  issue 445542  "WebGL High-Resolution Problem" for additional background.

https://crrev.com/c/1153483 changes the GetImage logic to return a DrawingBuffer-sized image in the downscaling case. This makes the transport work consistently, though the webvr.info test page does not handle this case correctly, resulting in an incorrect eye split.

It appears that many WebGL applications assume that the canvas size equals the drawing buffer size, and break if there's an unexpected mismatch.

To avoid application issues, I think we should revisit the arbitrary kMaxArea limit and only apply it on the specific GPUs or systems where it's actually needed as a workaround, but that's a separate issue.
Project Member

Comment 10 by bugdroid1@chromium.org, Jul 27

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/c821960613e9a846329da5cad385ee55af95bdcb

commit c821960613e9a846329da5cad385ee55af95bdcb
Author: Klaus Weidner <klausw@chromium.org>
Date: Fri Jul 27 20:04:56 2018

Use drawing buffer size for webgl canvas GetImage

The kMaxArea downsizing logic in WebGLRenderingContextBase::Reshape
causes the drawing buffer size to be smaller than the canvas size
if the size would exceed 16 MiPixels. See  https://crbug.com/445542 
for additional background.

The GetStaticBitmapImage has two separate implementations that
are selected based on the preserve_drawing_buffer attribute. The
non-preserving mode returns an image sized to match the drawing buffer,
while the preserving snapshot used the canvas size.

Change GetImage to use the drawing buffer size also for consistency.

BUG=845742

Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel
Change-Id: I8cb00444e18f075abde881c5bb155ef039f7a68e
Reviewed-on: https://chromium-review.googlesource.com/1153483
Reviewed-by: Brandon Jones <bajones@chromium.org>
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Commit-Queue: Klaus Weidner <klausw@chromium.org>
Cr-Commit-Position: refs/heads/master@{#578761}
[modify] https://crrev.com/c821960613e9a846329da5cad385ee55af95bdcb/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc

It might be worth blocking this on Issue 756347. That work stalled due to the difficulty of generally lifting the WebGL canvas size restrictions, but it might be feasible to land it in some form.

Blockedon: 756347
Blocking: 841062
Status: Assigned (was: Available)
Components: Internals>XR
Removing Internals>VR component and assigning to Internals>XR
Components: -Internals>VR
Blocking: 773882

Sign in to add a comment