KhronosGroup / KhronosGroup/WebGL
Need an explicit API or formula for setting a pixel-perfect canvas size.
- Dominant language
- HTML
- Stars
- 2.9k
- Forks
- 703
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 4
Description
Rendering unscaled pixel-perfect content to pages with fractional devicePixelRatio is ambiguous. Reading the wiki page at https://www.khronos.org/webgl/wiki/HandlingHighDPI , the page says:
"Experimentation has revealed that in order to precisely compute the number of device pixels covered by a particular element, heuristics may be necessary; whether to use Math.round() or Math.floor() may depend on such things as the current level of browser zoom."
This is not acceptable. Reading e.g. here http://www.quirksmode.org/blog/archives/2012/07/more_about_devi.html , it seems that there are devices out there that have a devicePixelRatio of 2.25 with device size of 720x1200 and dips size of 320x533. Computing `Math.round(533*2.25) = 1199` and `Math.floor(533*2.25)=1199`, so in that case one would have to use `Math.ceil(533*2.25) = 1200` to get the correct result for a fullscreen per-pixel perfect canvas, unlike round or floor like the guide suggests.
When the canvas is not fullscreen, but arbitrarily sized on a page, there is apparently no formula/algorithm to guarantee how to resize the canvas so that its content will be displayed pixel-perfect on the page(?), but annoying off-by-one-pixel artifacts can occur, and even more costly, the browser cannot optimize blitting when it has to stretch to resize a canvas width and height up or down by one pixel.
We cannot continue to rely on heuristics that are impossible to get right. We need an explicit api that will guarantee to produce pixel-perfect WebGL rendering. For example, such an api could look like:
```
var canvas = document.getElementById('canvas');
var deviceSize = canvas.sizeInDevicePixels(); // Query the canvas to tell what size its rendering surface should be set to in order to perform pixel-perfect rendering.
canvas.width = deviceSize.width;
canvas.height = deviceSize.height;
canvas.getContext('webgl');
```
or similar. Alternatively, we need an exact codified procedure that is documented in the spec and guaranteed to give a pixel-perfect match and one that works even when devicePixelRatio is arbitrary fractional like 2.25 reported in the wild.
Does anyone know if there already exists such a guarantee by WebGL/canvas/some other specification? Perhaps the wiki page just explains bad practices?
Contributor guide
Research direction
Start with the linked Khronos WebGL wiki page and the QuirksMode device-pixel-ratio example, then review the canvas and WebGL specifications for existing sizing guarantees. The work would be complete only when the project has either an explicit API or a precisely documented procedure that handles fractional devicePixelRatio values without heuristic off-by-one results.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- computer-graphics, web-dev
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100