Open Bug 1674681 Opened 11 months ago Updated 11 months ago

Setting devPixelsPerPx to 1.75 causes rounding error and blurry canvas

Categories

(Core :: Graphics, defect, P3)

Firefox 84
defect

Tracking

()

People

(Reporter: ishitatsuyuki, Unassigned)

Details

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36 Edg/86.0.622.56

Steps to reproduce:

Set layout.css.devPixelsPerPx to 1.75 in about:config. Or simply use Firefox on a computer with 175% scaling factor.

Actual results:

window.devicePixelRatio becomes 1.7647058823529411 which is a 0.8% "drift". This results in canvas applications becoming blurry, since they can no longer render to physical pixels 1:1. (Can be tested with PDF.js: https://mozilla.github.io/pdf.js/web/viewer.html)

Expected results:

The DPR should be accurate for precisely presentable floating point values. (e.g. 1.75, 1.125 is accurately representable, but 1.1, 1.3 is not.)

AppUnitsPerCSSPixel() = 60.[1]

mAppUnitsPerDevPixelAtUnitFullZoom = round(AppUnitsPerCSSPixel / devPixelsPerCSSPixel(1.75)) = 34.[2]

nsDeviceContext::mAppUnitsPerDevPixel = round(mAppUnitsPerDevPixelAtUnitFullZoom) / mFullZoom) = mAppUnitsPerDevPixelAtUnitFullZoom = 34.[3] (Assuming full zoom is not applied.)

nsDeviceContext::AppUnitsPerDevPixel() = nsDeviceContext::mAppUnitsPerDevPixel = 34.[4]

mCurAppUnitsPerDevPixel = mDeviceContext->AppUnitsPerDevPixel() = 34.[5]

nsPresContext::AppUnitsPerDevPixel() = mCurAppUnitsPerDevPixel = 34.[6]

devicePixelRatio = AppUnitsPerCSSPixel() / presContext->AppUnitsPerDevPixel() = 60 / 34 = 1.764705882352941.[7]

[2] brings the rounding error.

Status: UNCONFIRMED → NEW
Component: Untriaged → Graphics
Ever confirmed: true
Product: Firefox → Core

Great investigation, Masatoshi! Talking to folks from gfx team, it sounds like changing mAppUnitsPerDevPixelAtUnitFullZoom to be floating point is the way to go, but it may be associated with quite a bit of implementation complexity.

Severity: -- → S3

I'm not sure about this, unfortunately.
This was more or less explored here: https://github.com/KhronosGroup/WebGL/issues/2460#issuecomment-624463142

It comes down to asking what DPR is for.
In particular, at "175%" 1920x1080 becomes one of two things:

  • 1097.142 x 617.142 @ dpr: 1.750
  • 1088.000 x 612.000 @ dpr 1.7647058823529411 (current behavior)
No longer blocks: gfx-triage
Priority: -- → P3
You need to log in before you can comment on or make changes to this bug.