Open
Bug 1232491
(displayport-api)
Opened 9 years ago
Updated 2 years ago
Expose the displayport to web content
Categories
(Core :: Panning and Zooming, enhancement, P3)
Core
Panning and Zooming
Tracking
()
NEW
Tracking | Status | |
---|---|---|
firefox48 | --- | unaffected |
People
(Reporter: kats, Unassigned)
References
(Blocks 6 open bugs)
Details
(Whiteboard: [gfx-noted])
In Orlando we discussed exposing the displayport to web content so that they can better implement things like infinite lists or scrolling of giant things without putting everything into the DOM from the get-go.
Doing this is straightforward enough but we had a long discussion about the API - whether it should be exposed on the DOM, if we should fire an event, or both. The general consensus was that we should fire an event to notify content of updates to the displayport, but not actually expose it on the DOM for content to read whenever it feels like. There were two main reasons that I captured:
1) We want to avoid the scenario where they can trigger a layout flush by reading the displayport. If we allowed that they could get into a loop where they do something in a scroll event listener and then read the displayport which would trigger a layout flush and new scroll event, or something of that nature. The alternative would be to return a stale displayport which isn't great either
2) It's easy enough to polyfill the DOM property using the displayport from the event, and it's much easier to add the property later than it would be to remove it later.
Reporter | ||
Comment 1•9 years ago
|
||
While poking around in the CodeMirror issue list I saw this issue which is a real-world example of thing we're trying to solve.
status-firefox46:
affected → ---
Updated•9 years ago
|
Flags: needinfo?(bgirard)
Comment 2•9 years ago
|
||
I think YouTube might be doing something similar too, see bug 1233585, though I doubt they'd want to use this solution.
Comment 3•9 years ago
|
||
I was planning on writing this up as a proposal for www-style over the holidays, unless someone particularly wanted to do it.
Reporter | ||
Comment 4•9 years ago
|
||
Go for it. The only thought I had about this was that if we are firing an event with the displayport, we should do so from the refresh driver, after the scroll event is fired. That way the displayport we announce remains as valid as we can make it until the next scroll event.
Comment 5•9 years ago
|
||
I'm concerned about avoiding doing 2 layout flushes in the optiomal case, particularly on page load:
1) Flush layout to know the size of the frame
2) Fire the event, page modifies the DOM
3) Flush layout again before we can paint.
We should think carefully about what guarantees we want to provide here. For instance if we have loose guarantee we could not fire the event on page load to not regress first paint.
Flags: needinfo?(bgirard)
Comment 7•9 years ago
|
||
Bikeshedding here...if we expose this to webcontent we might want to use the name renderport instead of displayport.
Reporter | ||
Comment 9•9 years ago
|
||
This may or may not overlap with the intersection observer proposal. In particular at [1] it says "Implementing data-bound high-performance scrolling lists which load and render subsets of data sets. These lists are a central mobile interaction idiom." which sounds very related.
[1] https://github.com/WICG/IntersectionObserver/blob/master/explainer.md
Comment 10•9 years ago
|
||
I had a read of that spec.
The current proposal allows you to specify a margin (either pixels or %) around the viewport when setting up an observer, and will provide notifications when an observed elements enters or leaves that area. This is the suggested usage for implementing 'data scrollers'.
We could propose an extension to this that instead allowed you to specify the 'render port' as the area you wanted to get notifications for (either by specifying the base rect, or a special keyword for the margin property).
I'm still not sure that this covers what we want entirely though, since the notifications are delivered asynchronously. You'd still have the issue where a placeholder enters the 'render port', gecko would render the placeholder, and then the web content gets the notification, adds the content and then we have to render the same pixels again.
The best solution in this model would be for web content to observe 'render port' + N pixel margin, where the margin is to buy enough time to get the notification and the content added before the placeholder enters the actual 'render port'.
Our initial idea was to instead have a synchronous callback (fired right before we paint, similar to rAF), that notifies web content of the 'render port' that we're about to render with (and we would probably not fire more events if you make changes that result in the actual 'render port' changing). There's no need to guess a saftey margin with this model.
The 'render port' + margin observer still seems useful for web content that wants to do async loading of data though.
It seems like we might want the concept of 'render ports' added to IntersectionObserver, as well as adding the event that we initially wanted. That might be a big ask though.
Does anyone have any thoughts on this?
Reporter | ||
Comment 11•9 years ago
|
||
(In reply to Matt Woodrow (:mattwoodrow) from comment #10)
> Our initial idea was to instead have a synchronous callback (fired right
> before we paint, similar to rAF), that notifies web content of the 'render
> port' that we're about to render with (and we would probably not fire more
> events if you make changes that result in the actual 'render port'
> changing). There's no need to guess a saftey margin with this model.
>
> The 'render port' + margin observer still seems useful for web content that
> wants to do async loading of data though.
Yeah I agree with this summary - I think we should have the sync callback specifically for rendering content that's already in-memory, and the async loading of data can be done with a margin observer.
Considering this, I think it probably makes sense to keep the proposals separate, although indicate to authors that if they are using this displayport callback, then can also use the intersection observer API for async loading of content.
Reporter | ||
Comment 12•9 years ago
|
||
Reporter | ||
Updated•9 years ago
|
status-firefox48:
--- → unaffected
Updated•9 years ago
|
Alias: displayport-api
Reporter | ||
Comment 13•8 years ago
|
||
Matt, do you know if we always fall back to software if a HTML canvas is larger than the max texture size?
The reason I ask is that in bug 1316318 comment 10 I suggested to :zer0 that we could use this displayport API to implement a "virtual canvas" much like a virtual list, to get around size limitations of canvas elements. He wrote a prototype [1], and used the max texture size in order to size his canvas (since we don't actually expose the displayport API yet). However, he discovered that for his retina MBP with intel graphics, the max texture size is quite small. So if we can guarantee that a canvas sized to the displayport exposed by this API would always render properly, then we can probably go further with that approach. Otherwise we'll have to find some other way to solve the problem.
[1] https://zer0.github.io/devtools/virtual-canvas.html
Flags: needinfo?(matt.woodrow)
Updated•8 years ago
|
Comment 14•8 years ago
|
||
Yeah, canvas bigger than the max texture size should fall back to software and will upload to the GPU in tiles.
We have automated tests that check that this works too, so it should be safe to rely on.
Flags: needinfo?(matt.woodrow)
Comment 15•8 years ago
|
||
katz, having this API apparently is becoming more and more important, so let me know when you have time to take a look! Thanks a lot!
Flags: needinfo?(bugmail)
Comment 17•8 years ago
|
||
@Kartikaya: I was reading through this bug and I don't understand how exposing the displayport to web content would solve the problem we have in bug 1308441 - i.e. using react-virtualized is broken since APZ causes transitory blank screen to appear during scrolling (there is a lag before the content is re-rendered). If I understand correctly the display port is the visible part of a page?
Honza
Blocks: 1308441
Flags: needinfo?(bugmail)
Reporter | ||
Comment 18•8 years ago
|
||
(In reply to Jan Honza Odvarko [:Honza] from comment #17)
> If I understand correctly the display port is
> the visible part of a page?
The displayport is the part of the page that Gecko pre-renders to minimize checkerboarding when scrolling. The transitory screen blank you're seeing is a form of checkerboarding (because Gecko scrolls asynchronously from painting, the user can scroll into a part of the page that hasn't been painted yet - hence the blank). I don't think exposing the displayport API will fix it *completely* but it exposes an easy-to-use API that gives web content a better idea of how much area to pre-render. The only other way to reduce the blanking is to paint faster which is a harder problem to solve (but which we are also working on with the Quantum projects).
Flags: needinfo?(bugmail)
Reporter | ||
Comment 19•8 years ago
|
||
Also, last week I spent a bit of time hacking up a prototype of this just to get an idea of how it would work. I have patches [1] and a try build with the patches [2]. I also took :zer0's virtual-canvas page [3] and modified it [4] to use the displayport API that I added (which is exposed as Element.addRenderCallback(function(rect) { ... })). I only fiddled with it enough to get the basic case working on my macbook air, so I haven't tuned it or optimized it or tested it on Retina/hidpi displays or anything but if you want to take a look and experiment with it, here it is.
[1] https://github.com/staktrace/gecko-dev/commits/displayportapi
[2] https://treeherder.mozilla.org/#/jobs?repo=try&revision=57cbc20f59467f35267a0eb74ff039a44f0c7bec
[3] https://zer0.github.io/devtools/virtual-canvas.html
[4] https://mozilla.staktrace.com/bug/1232491/virtual-canvas-dp.html
Updated•7 years ago
|
Priority: -- → P3
Comment 20•3 years ago
|
||
Type: defect → enhancement
Updated•2 years ago
|
Severity: normal → S3
You need to log in
before you can comment on or make changes to this bug.
Description
•