Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Web canvas resize loop #4699

Open
alexkirsz opened this issue Jun 24, 2024 · 10 comments
Open

Web canvas resize loop #4699

alexkirsz opened this issue Jun 24, 2024 · 10 comments
Labels
bug Something is broken docs and examples Improving and adding documentation and examples web Related to running Egui on the web

Comments

@alexkirsz
Copy link

Describe the bug
#4536 introduced a ResizeObserver-based resizing for the canvas. Testing it with rerun, when the size of the canvas isn't explicitly bounded via CSS, the canvas quickly enters a resize loop where:

  1. A first resize entry is fired after the first call to .observe. In the callback, the canvas is resized to the measured device pixel size. For instance, if the device pixel ratio is 2 and the canvas size hasn't been explicitly set via CSS, the canvas will be resized from 300x150 (logical pixels) to 600x300 (physical pixels).
  2. The resize causes a new resize entry to be fired. This time, the canvas will be resized from 600x300 to 1200x600.
  3. etc.
  4. This quickly causes rerun/egui to crash from trying to instantiate too large a texture.
@alexkirsz alexkirsz added the bug Something is broken label Jun 24, 2024
@emilk
Copy link
Owner

emilk commented Jun 24, 2024

Seems like there is some place where we confuse units (logical vs physical pixels).

@jprochazk can you take a look?

@jprochazk
Copy link
Collaborator

jprochazk commented Jun 24, 2024

Can you provide a repro, e.g. what your HTML/CSS was when embedding rerun in a page? egui doesn't resize the canvas.

Also note that the ResizeObserver changes haven't even been released yet, so make sure you're testing with the latest main of rerun.

@alexkirsz
Copy link
Author

Can you provide a repro, e.g. what your HTML/CSS was when embedding rerun in a page?

Sure! Is there a working codesandbox template I could fork to try to repro the issue there? I currently have a custom setup with a local build of the rerun viewer running in a Next.js app, so it would be hard to extract, but I think I should be able to repro it in isolation.

egui doesn't resize the canvas.

These two lines are where the problem stems from in eframe.

@jprochazk
Copy link
Collaborator

These two lines are where the problem stems from in eframe.

That doesn't resize the canvas display size, which is the problem you're experiencing. It changes the number of pixels in the canvas drawing buffer. Here's a good writeup about the difference: https://stackoverflow.com/a/43364730

@alexkirsz
Copy link
Author

In the absence of any CSS explicitly setting the size of the canvas, the width and height attributes of the canvas will also affect its display size: https://codesandbox.io/s/musing-mendeleev-342tww

@jprochazk
Copy link
Collaborator

jprochazk commented Jun 24, 2024

Right, so that's a problem, because:

  • We set width/height attributes to ensure the drawing buffer has the correct size
  • We scale the width/height by DPR to ensure sharp text rendering on high-DPI or during browser zoom

Is there a reason why you can't set width/height style on the canvas in your setup? I don't think there's anything we can do about this in egui/eframe. Settings those attributes is a requirement to make egui's rendering work.

@alexkirsz
Copy link
Author

The original reason was that rerun's WebViewer API doesn't provide direct control over the underlying canvas element and I had not styled it properly. This behavior from eframe was surprising to me and I think it might make sense to add a circuit breaker here to at least print out an error when this loop is encountered. With proper styling, this isn't an issue.

@jprochazk
Copy link
Collaborator

jprochazk commented Jun 24, 2024

I agree that it is surprising. We'll have to think about how best to detect this, and document that users are expected to set the canvas size through CSS.

As for the rerun viewer, just today we merged a PR that exposes the underlying canvas as a property on the WebViewer. You can access it that way if you update to latest main, so something like viewer.canvas.classList.add("custom-canvas-style") will work. We're committed to making sure that the only element the web viewer appends to the provided parent element is the canvas, so selectors like .your-parent-element > canvas should always work as well.

jprochazk added a commit to rerun-io/rerun that referenced this issue Jun 26, 2024
### What

We now set the web viewer CSS width/height to some default values, which
can be modified by the user. Setting them to empty strings is allowed to
disable the default values completely, and allow styling the canvas
through other means as before.

This is meant as a mitigation for
emilk/egui#4699 - by setting the CSS
width/height to _something_, the canvas width/height attributes won't
contribute to the display size of the canvas.

Tested in https://github.com/rerun-io/web-viewer-example by manually
linking the package

### Checklist
* [x] I have read and agree to [Contributor
Guide](https://github.com/rerun-io/rerun/blob/main/CONTRIBUTING.md) and
the [Code of
Conduct](https://github.com/rerun-io/rerun/blob/main/CODE_OF_CONDUCT.md)
* [x] I've included a screenshot or gif (if applicable)
* [x] I have tested the web demo (if applicable):
* Using examples from latest `main` build:
[rerun.io/viewer](https://rerun.io/viewer/pr/6636?manifest_url=https://app.rerun.io/version/main/examples_manifest.json)
* Using full set of examples from `nightly` build:
[rerun.io/viewer](https://rerun.io/viewer/pr/6636?manifest_url=https://app.rerun.io/version/nightly/examples_manifest.json)
* [x] The PR title and labels are set such as to maximize their
usefulness for the next release's CHANGELOG
* [x] If applicable, add a new check to the [release
checklist](https://github.com/rerun-io/rerun/blob/main/tests/python/release_checklist)!

- [PR Build Summary](https://build.rerun.io/pr/6636)
- [Recent benchmark results](https://build.rerun.io/graphs/crates.html)
- [Wasm size tracking](https://build.rerun.io/graphs/sizes.html)

To run all checks from `main`, comment on the PR with `@rerun-bot
full-check`.
@emilk
Copy link
Owner

emilk commented Jun 26, 2024

How do we document this better? In web_demo/index.html maybe, and link to that from the eframe docs?

@abey79
Copy link
Collaborator

abey79 commented Sep 29, 2024

I got pretty badly hit by that when trying to updated my own project from 0.27.

Fixed it by applying the following patch to the CSS (which I had originally copied from egui's template):

             margin-left: auto;
             display: block;
             position: absolute;
-            top: 0%;
-            left: 50%;
-            transform: translate(-50%, 0%);
+            top: 0;
+            left: 0;
+            width: 100%;
+            height: 100%;
         }
 
         .centered {

[For discoverability/searchability] This created these warnings in the console:

ResizeObserver loop completed with undelivered notifications.

and cascaded into the following, texture-related crash (as noted by OP):

panicked at /Users/hhip/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wgpu-22.1.0/src/backend/wgpu_core.rs:786:18:
Error in Surface::configure: Validation Error

Caused by:
  `Surface` width and height must be within the maximum supported texture size. Requested was (9600, 4800), maximum extent for either dimension is 8192.


Stack:

@http://127.0.0.1:4000/whiskers_web_demo.js:490:30
whiskers_web_demo.wasm.wasm-function[eframe::web::panic_handler::PanicSummary::new::ha825664bab6fbfd5]@[wasm code]
whiskers_web_demo.wasm.wasm-function[eframe::web::panic_handler::PanicHandler::install::{{closure}}::h0e7bb6b396cb6c30]@[wasm code]
whiskers_web_demo.wasm.wasm-function[std::panicking::rust_panic_with_hook::h6731baa78621a747]@[wasm code]
whiskers_web_demo.wasm.wasm-function[std::panicking::begin_panic_handler::{{closure}}::hb6cd8464ed39ae71]@[wasm code]
whiskers_web_demo.wasm.wasm-function[std::sys_common::backtrace::__rust_end_short_backtrace::hbdf3ddeb21a1e747]@[wasm code]
whiskers_web_demo.wasm.wasm-function[rust_begin_unwind]@[wasm code]
whiskers_web_demo.wasm.wasm-function[core::panicking::panic_fmt::h5c7ce52813e94bcd]@[wasm code]
whiskers_web_demo.wasm.wasm-function[wgpu::backend::wgpu_core::ContextWgpuCore::handle_error_fatal::hdd0cd80465d23ce9]@[wasm code]
whiskers_web_demo.wasm.wasm-function[<wgpu::backend::wgpu_core::ContextWgpuCore as wgpu::context::Context>::surface_configure::h53ae88b4e398ff06]@[wasm code]
whiskers_web_demo.wasm.wasm-function[<T as wgpu::context::DynContext>::surface_configure::hea72b84598516a83]@[wasm code]
whiskers_web_demo.wasm.wasm-function[wgpu::Surface::configure::h0b5bfdd73d26be35]@[wasm code]
whiskers_web_demo.wasm.wasm-function[<eframe::web::web_painter_wgpu::WebPainterWgpu as eframe::web::web_painter::WebPainter>::paint_and_update_textures::h75e45eb12ab4ffe8]@[wasm code]
whiskers_web_demo.wasm.wasm-function[eframe::web::app_runner::AppRunner::paint::h0185300c231042be]@[wasm code]
whiskers_web_demo.wasm.wasm-function[eframe::web::events::paint_if_needed::h92bac454e039304d]@[wasm code]
whiskers_web_demo.wasm.wasm-function[eframe::web::events::install_resize_observer::{{closure}}::hb00b4342b2ab0554]@[wasm code]
whiskers_web_demo.wasm.wasm-function[<dyn core::ops::function::FnMut<(A,)>+Output = R as wasm_bindgen::closure::WasmClosure>::describe::invoke::h1635b6c4d8865d58]@[wasm code]
__wbg_adapter_37@http://127.0.0.1:4000/whiskers_web_demo.js:236:134
real@http://127.0.0.1:4000/whiskers_web_demo.js:207:21

@emilk emilk added this to the Next Major Release milestone Sep 30, 2024
@emilk emilk added docs and examples Improving and adding documentation and examples web Related to running Egui on the web labels Dec 11, 2024
@emilk emilk removed this from the Next Major Release milestone Dec 11, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something is broken docs and examples Improving and adding documentation and examples web Related to running Egui on the web
Projects
None yet
Development

No branches or pull requests

4 participants