Closed Bug 1041225 Opened 7 years ago Closed 7 years ago

Generating a screenshot is very slow when the content canvas has obnoxious dimensions

Categories

(DevTools Graveyard :: Canvas Debugger, defect)

defect
Not set
normal

Tracking

(Not tracked)

RESOLVED FIXED
Firefox 34

People

(Reporter: vporof, Assigned: vporof)

Details

Attachments

(1 file, 1 obsolete file)

For example, http://workshop.chromeexperiments.com/stars/ builds a canvas that is window.width * window.height * window.devicePixelRatio in size, which can end up being over 2K by 2K in size. Obviously, generating a screenshot in this case is slow.

Fortunately, with some framebuffer and viewport magic, we can render the exact same content on a smaller buffer, and extract the (greatly reduced in size) image data afterwards.
Attached patch v1 (obsolete) — Splinter Review
Assignee: nobody → vporof
Status: NEW → ASSIGNED
Attachment #8459233 - Flags: review?(rcampbell)
Actually, the demo in comment 0 is building a canvas that's 5760 x 3008 (although it's stretched to fit the browser window).
Attached patch v2Splinter Review
Also prevent content calls to gl.viewport while rendering to our custom framebuffer.
Attachment #8459233 - Attachment is obsolete: true
Attachment #8459233 - Flags: review?(rcampbell)
Attachment #8459239 - Flags: review?(rcampbell)
Comment on attachment 8459239 [details] [diff] [review]
v2

Review of attachment 8459239 [details] [diff] [review]:
-----------------------------------------------------------------

one question below. r+

::: toolkit/devtools/server/actors/canvas.js
@@ +615,5 @@
> +      // of smaller dimensions than the actual canvas (maximum 512x512 pixels).
> +      let scaling = Math.min(CanvasFront.WEBGL_SCREENSHOT_MAX_HEIGHT, h) / h;
> +      replayContextScaling = scaling;
> +      w = ~~(w * scaling);
> +      h = ~~(h * scaling);

augh!

is this faster than Math.floor()?

@@ +797,5 @@
>  CanvasFront.ANIMATION_GENERATORS = new Set(ANIMATION_GENERATORS);
>  CanvasFront.DRAW_CALLS = new Set(DRAW_CALLS);
>  CanvasFront.INTERESTING_CALLS = new Set(INTERESTING_CALLS);
>  CanvasFront.THUMBNAIL_HEIGHT = 50; // px
> +CanvasFront.WEBGL_SCREENSHOT_MAX_HEIGHT = 256; // px

am I right in thinking that the max size of these is actually 512px? Are we limiting to 256 for UI sensibility reasons, but capping the framebuffer at 512?
Attachment #8459239 - Flags: review?(rcampbell) → review+
(In reply to Rob Campbell [:rc] (:robcee) from comment #4)
> Comment on attachment 8459239 [details] [diff] [review]
> 
> am I right in thinking that the max size of these is actually 512px? Are we
> limiting to 256 for UI sensibility reasons, but capping the framebuffer at
> 512?

The comment above is actually incorrect, it's 256 all the way. Since the preview pane is likely to never be bigger than that, I'd say it's a nice size to cap to.
(In reply to Rob Campbell [:rc] (:robcee) from comment #4)
> 
> ::: toolkit/devtools/server/actors/canvas.js
> @@ +615,5 @@
> > +      // of smaller dimensions than the actual canvas (maximum 512x512 pixels).
> > +      let scaling = Math.min(CanvasFront.WEBGL_SCREENSHOT_MAX_HEIGHT, h) / h;
> > +      replayContextScaling = scaling;
> > +      w = ~~(w * scaling);
> > +      h = ~~(h * scaling);
> 
> augh!
> 
> is this faster than Math.floor()?
> 

Yes.
https://hg.mozilla.org/mozilla-central/rev/3d091524a1b8
https://hg.mozilla.org/mozilla-central/rev/ab11981ffeb0
Status: ASSIGNED → RESOLVED
Closed: 7 years ago
Flags: in-testsuite+
Resolution: --- → FIXED
Whiteboard: [fixed-in-fx-team]
Target Milestone: --- → Firefox 34
Product: Firefox → DevTools
Product: DevTools → DevTools Graveyard
You need to log in before you can comment on or make changes to this bug.