Open Bug 780362 Opened 12 years ago Updated 2 years ago

[HiDPI] Implement high-dpi canvas drawing / backing stores

Categories

(Core :: Graphics: Canvas2D, defect)

All
macOS
defect

Tracking

()

People

(Reporter: fxcoudert, Unassigned)

References

(Blocks 1 open bug, )

Details

Attachments

(1 file)

User Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:17.0) Gecko/17.0 Firefox/17.0
Build ID: 20120803090747

Steps to reproduce:

Using the HiDPI-enabled build on bug 674373's comment 138 (https://bugzilla.mozilla.org/show_bug.cgi?id=674373#c138), Canvas content is displayed at low resolution, instead of the expected high resolution.

All canvas operations are performed in low resolution mode (and thus give blurry rendering). See the attached screenshot of this page: https://developer.mozilla.org/samples/canvas-tutorial/2_5_canvas_quadraticcurveto.html where patched FF is on the left, and Safari on the right.

This can also be seen on the pdf.js PDF viewer, which is entirely rendered in low resolution (and thus blurry).
Depends on: 674373
For backwards compatibility, canvas needs to default to low-res. However, the WHATWG canvas spec recently gained a mechanism for scripts to opt into a high-res canvas backing store. Gecko needs to support that.
Component: Untriaged → Canvas: 2D
Product: Firefox → Core
Version: 17 Branch → Trunk
Note: pdf.js relies on canvas for rendering so HiRes display of PDF files in pdf.js will also depend on this.
Summary: Canvas drawing is not high-resolution on Retina display → [HiDPI] Canvas drawing is not high-resolution on Retina display
(In reply to Henri Sivonen (not reading bugmail until 2012-09-17) (:hsivonen) from comment #1)
> For backwards compatibility, canvas needs to default to low-res. However,
> the WHATWG canvas spec recently gained a mechanism for scripts to opt into a
> high-res canvas backing store. Gecko needs to support that.

Can you provide a link?  I can't find any such opt-in details in the spec, but I may not be looking in the right place.
(In reply to Vladimir Vukicevic [:vlad] [:vladv] from comment #3)
> (In reply to Henri Sivonen (not reading bugmail until 2012-09-17)
> (:hsivonen) from comment #1)
> > For backwards compatibility, canvas needs to default to low-res. However,
> > the WHATWG canvas spec recently gained a mechanism for scripts to opt into a
> > high-res canvas backing store. Gecko needs to support that.
> 
> Can you provide a link?  I can't find any such opt-in details in the spec,
> but I may not be looking in the right place.

It seems I had it wrong. The backing store doesn't default to low-res. Instead, old bitmap getters and setters always use low-res data, so a JS program has to opt in to being exposed to hi-res bitmaps by using *HD variants of methods that deal with bitmap data.

Querying the backing store size:
http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#resolution

New HD methods:
http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-getimagedatahd
http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-putimagedatahd
http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-createimagedatahd
The backing store _should_ default to low-res though. Automatically upsampling when drawing images and downsampling again for getImageData() will break many applications that need to analyze actual image pixels (e.g. scaling algorithms like this: https://github.com/phoboslab/js-hqx ).

Here's a test case (currently broken in Safari 6): 
http://www.phoboslab.org/****/backingstore/

And a blog post describing some of the problems further:
http://www.phoboslab.org/log/2012/09/drawing-pixels-is-hard

Please consider making high-res opt-in or at least give us a way to easily opt-out.
(In reply to Dominic Szablewski from comment #5)
> Here's a test case (currently broken in Safari 6): 
> http://www.phoboslab.org/****/backingstore/

The asterisks mark a word not allowed on Bugzilla.

To find the right URL, navigate to
> http://www.phoboslab.org/log/2012/09/drawing-pixels-is-hard
and then navigate to the test case using the link in the last paragraph of the post.
(In reply to Dominic Szablewski from comment #5)
> Please consider making high-res opt-in or at least give us a way to easily
> opt-out.

Sadly, across the Web, opt-out probably makes more sense, since we can assume people like you can figure out how to opt-out but people who are using <canvas> for charts already made the mistake of not using SVG, so it would be over-optimistic to expect them to suddenly be clued-in enough to opt into a high-res backing store.
This bug is a major drawback for at least one reason: canvas drawing is used by pdf.js, so that viewing PDF files inside the browser in current nightly is a horrible experience (completely blurry). Whatever solution is standardized, something needs to be done at least for the built-in PDF renderer.
fwtw increasing canvas size by 200% and applying CSS transform with scale 50% on canvas element produces nice output with desired size.

(tried using http://stackoverflow.com/questions/12124576/how-to-simulate-a-retina-display-hidpi-mode-in-mac-os-x-10-8-mountain-lion-on -- has no retina display atm)
Blocks: 678392
Status: UNCONFIRMED → NEW
Ever confirmed: true
Hardware: x86 → All
Summary: [HiDPI] Canvas drawing is not high-resolution on Retina display → [HiDPI] Implement high-dpi canvas drawing / backing stores
Blocks: 836430
(In reply to Yury Delendik (:yury) from comment #10)
> fwtw increasing canvas size by 200% and applying CSS transform with scale
> 50% on canvas element produces nice output with desired size.

I can confirm that I've used this workaround successfully for high-resolution canvas drawing on a Retina Mac. Cross-browser code here:
https://github.com/luser/asteroids/blob/master/asteroids.js#L42
Note that Apple's Safari *used to* default to a high-res canvas/backing store on Retina displays but that confused the hell out of web developers and they've gone back to a low-res backing store in more recent versions, with recommendation to set the width/height etc based on window.devicePixelRatio manually if you need full-resolution display.

The old linked provisional extensions to the canvas API don't seem to be in current specs either, so I think that's pretty much dead and manual resizing is the recommended solution all around.
Blocks: 1382560
No longer blocks: 1382560
No longer blocks: history-swipe
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: