Advanced-Layers, Continued
REPO: https://github.com/dvander/gecko-dev/tree/al
PREF: layers.mlgpu.dev-enabled to true
---------------------------------------------------------------------
TODO List: (1=easy 5=hard
Post-Landing:
- right-size intermediate surfaces in LayerTreeInvalidation (bug 1375785)
- log after computing effective regions
- fix bad call to VSSetConstantBuffers in EndFrame
TODO DONE
[?] Default clear color? DOCUMENTED[1] Remove MLGBufferDesc and MLGBindFlags DONE[2] Make MLGDevice initialization more log-y[1] MayResample[1] Make sure ASAP mode works OK[1] Detect shader model 4 earlier WONTFIX[1] Force Present[?] Missing floor in nojs NOT AL, HAPPENS ON NIGHTLY[1] Block rendering previous frame[1] Initialize MLGDevice off the main thread[2] Checkerboarding, if bug 1349418 doesn't pan out (bug 1349418 landed)[1] Telemetry histogram for failures[1] Blocklist functionality[1] Propagate MLGDevice creation failure to the UI[0] Remove unnecessary MOZ_COUNT_CTOR/DTOR[2] Improve mask rect allocation logic[2] memory use logging for constant buffers, etc[2] Improve SharedBufferMLGPU allocation sizes[2] ClearCachedRersources[3] LayerTreeInvalidation integration[?] Partial presents[1] Widget composite callbacks[2] Audit use of LM::GetCompositor[1] Audit unimplemented APIs[0] Profiler labels[0] Frame time recording functions[0] Warn when present fails[2] Handle device resets/stale textures - need bug 1363126[1] Move ContainerLayer into its own file[3] Bas's double-buffer optimizations[2] Cache MLGBuffers from layer constant lists)ignore swapchain resizes for 0,0add a way to disable ClearViewupdate docs for shader modeluse visible region for colorreftest failures on shared constant buffer codeMLGTexture2Duse visible region for all drawsfix layer dump spew:not logging compositables
STUFF FOR ACTIVE LAYERS:
- [3] Re-introduce Matt's FrameMetrics optimizations (to land on central)
- [3] Minimize layer deltas (to land on central)
- [?] Walk APZCs for TransformShadowTree, not layers
- [?] caret layers? bug 866731
PROTOTYPE WORKLIST:
- [3] Implement mix-blend modes
- [5] Implement transform support
- [3] Implement DXGI/d2d/canvas texture support
- [2] Implement YUV video support
- [2] Implement component-alpha support
- [1] Implement SyncObject support
- [2] Implement general opacity support
- [1] Handle buffer allocation failure
- [1] Implement NV12 video support
- [5] Implement mask layers
- [4] Implement BigImage support
- [2] Remove tiling (for plane splitting)
- [6] Implement plane splitting
- [1] Lazy shader initialization
- [2] Rotate constant/vertex buffers when full
- [1] Split render passes when staging buffers are full
- [2] Retain render targets for performance
- [5] Use z-buffer for overlap
[3] Use textures instead of constant buffers NOT PERFORMANT- [2] Address APZ hit testing tree updates (active layers critical)
---------------------------------------------------------------------
Original notes are below, and most are still relevant:
---------------------------------------------------------------------
REPO: http://hg.mozilla.org/users/bschouten_mozilla.com/advanced-layers/
PREF: layers.advanced-layers.enabled to true to use the advanced layer manager on the compositor side
- Make TextLayer support multiple colors/fonts
- Build ContainerLayers around groups of scrolled layers that all share an AGR and only attach FM to the containers
- Optimize IPDL transfer of layer properties
- Optimize IPDL constructors and dtors
- Build ContainerLayers around things with masks, make sure that old-layers still optimizes this in the same way
- Don't serialize glyphs every time if they haven't changed
We can ask FrameLayerBuilder to only add an items to an existing painted layer if it overlaps the existing visible region. This should results in more PaintedLayer, but covering smaller area and reduce the chance of getting large empty areas.
layout.smaller-painted-layers = true to control this
Remove the #defined MOZ_PICKLE_SENTINEL_CHECKING from http://searchfox.org/mozilla-central/source/ipc/chromium/src/base/pickle.h#26 and see if it makes a performance difference to layer transaction reading/writing.
TODO:
- Implement accelerated video
- Support masking
- Support intermediate surfaces
Improving FrameMetrics serialization times:
It appears that creating a new FrameMetrics for each potentially scrolled layer and serializing them is slow.
A simple solution might be to treat them as a shared object that multiple layers reference. We could do this within the scope of a transaction, and not worry about retaining them between transactions.
FrameLayerBuilder calls ComputeScrollMetadata with the content of 'scrollClip' (DisplayItemScrollClip: the scrollframe, and DisplayItemClip), mContainerReferenceFrame and mParameters (which should be constant for all layers built by the current ContainerState) and the current layer pointer.
From what I can tell the layer pointer is only used when APZ is disabled (the !thisScrollFrameUsesAsyncScrolling branch in ScrollFrameHelper::ComputeScrollMetadata) and for logging in nsLayoutUtils::ComputeScrollMetadata.
So if ContainerState kept a map of DisplayItemScrollClip -> FrameMetrics then we could avoid computing these each time.
The DisplayItemClip member of DisplayItemScrollClip ('clip') is only used for a single property on the final FrameMetrics (metadata.SetScrollClip in nsLayoutUtils::ComputeScrollMetadata), so depending on how often this varies it might be valuable to split it into a separate object that isn't cached (or have a 2-level cache).
- <mstange> When would this be useful? If you have two identical DisplayItemScrollClips, then they also have the same clip...
- This is for the case where you have two layers that use the same nsIScrollableFrame*, but different DisplayItemClip/DisplayItemScrollClips. The computed ScrollMetadata for these would be 99% identical, so seems wasteful to duplicate all the work/memory. That said, it hasn't shown up as a big problem yet.
We could also consider retaining them between transactions, but then we need to consider invalidation for them and I haven't thought about that yet.
UPDATE:
I've written an initial prototype for the first half of this, putting ScrollMetadata on the heap (https://hg.mozilla.org/users/bschouten_mozilla.com/advanced-layers/rev/164fbd502abf) and caching them in FLB (https://hg.mozilla.org/users/bschouten_mozilla.com/advanced-layers/rev/6fe40bb08195). This makes a huge difference to the time spent within layer building.
Still to do:
* Share serializations of ScrollMetadata. Simplest thing to do is probably add a new Edit type for ScrollMetadata. When ShadowLayerForwarder finds a new ScrollMetadata*, it creates an edit to serialize that and puts a id number in to the layer attributes. LayerTransactionParent can do the reverse. IDs numbers would only be valid for the duration of the transaction. - DONE (https://hg.mozilla.org/users/bschouten_mozilla.com/advanced-layers/rev/718eac01414c)
* My patches currently have ScrollMetadataRefcounted. Once IPDL is sharing serialization, we probably won't many (any?) users of the non-refcounted version, so we can/should merge them back together.
* FLB checks the nsIScrollableFrame*/DisplayItemClip equality manually instead of comparing DisplayItemScrollClip pointers. Is it possible that this actually catches more cases? Likely? It would be faster to do pointer comparison so we can do that if it's not helping.
Improving TextLayer performance:
We currently re-serialize all glyphs each time we do a content-side paint.
We should be able to instead use the same data that DLBI uses to determine if the glyph list has changed, and only recompute and reserialize the glyphs if it has.
We currently Move() the glyph array into IPDL to avoid a copy, but if anything else mutates the layer (like a transform change) then we'd need to have recomputed the array again. One solution to that is to copy it into IPDL instead of moving, the other is separating SetGlyphs from the Mutated/TextLayerAttributes messages so that it only gets used when it actually changes.
Glyphs are also currently positioned relative to their reference frame, so their positions change on scroll. We could instead compute them relative to the Text element, and add an offset translation to the Layer which moves them to the correct position. We'd probably want to have implemented the second solution to the Move() problem so that we don't copy or send glyphs at all when scrolling.