# Delegated Compositing Failure [Delegated compositing](https://github.com/elkurin/elkurin-daily-notes/blob/main/docs/day12.md) is a mechanism for compositing in Server-Client model to reduce the performance overhead. In short, Client delegates all compositing to Server. It's enabled by default on Lacros but it seems Lacros fails to delegate compositing time to time. Let's see how it fails. ## OverlayProcessorDelegated [OverlayProcessorDelegated](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/overlay_processor_delegated.h;l=33;drc=e3c808e5986997a699f7fd4ed59bc5686276d9c5) is a class that attempts to promote to overlay all the draw quads of the root render pass. This is used by Lacros. Here, overlay means not hardware overlay but instead whether it can delegate compositing to Ash. Each render pass is attempted to promote to delegated compositing by [ProcessForOverlays](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/overlay_processor_delegated.cc;l=327;drc=8e78783dc1f7007bad46d657c9f332614e240fd8). It [AttemptWithStrategies](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/overlay_processor_delegated.cc;l=129;drc=8e78783dc1f7007bad46d657c9f332614e240fd8). [`delegated_state_`](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/overlay_processor_delegated.h;l=130;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) who is [DelegationStatus](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/overlay_processor_delegated.h;l=75;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) represents how the delegation went. If [delegated compositing feature](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/common/features.cc;l=55;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) is disabled, then it quits with [kCompositedFeatureDisabled](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/overlay_processor_delegated.h;l=87;drc=8e78783dc1f7007bad46d657c9f332614e240fd8). If there is a copy requrest on the root render pass, we fails to delegate with [kCompositedCopyRequest](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/overlay_processor_delegated.h;l=83;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) because we will end up with the delegated quads missing from the frame buffer, and also it may increase the power usage. If there is too many quads, it fails with [kCompositedTooManyQuads](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/overlay_processor_delegated.h;l=81;drc=8e78783dc1f7007bad46d657c9f332614e240fd8). By "too many", it means [64](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/overlay_processor_delegated.cc;l=125;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) in this case. Too many quads will harm the performance if we delegate it (?). If render pass backdrop filter is empty, it fails with [kCompositedBackdropFilter](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/overlay_processor_delegated.h;l=82;drc=8e78783dc1f7007bad46d657c9f332614e240fd8). TODO(elkurin): What is this? Now, it starts attempting to create [OverlayCandidate](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/overlay_candidate.h;l=40;drc=8e78783dc1f7007bad46d657c9f332614e240fd8). For each quad in `quad_list`, it generates OverlayCandidate. Using OverlayCandidateFactory, [FromDrawQuad](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/overlay_candidate_factory.cc;l=145;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) creates the candidate and return the success status. [kSuccess](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/overlay_candidate.h;l=46;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) will be returned if we can delegate the candidate. In this case, the material can be SolidColor, AggregatedRenderPass or roundad corners. This candidate will be pushed to OverlayCandidateList. If visible area is empty (empty `visible_rect`, `clip_rect` clips all area), it fails with [kFailVisible](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/overlay_candidate.h;l=56;drc=8e78783dc1f7007bad46d657c9f332614e240fd8). In this case, it increases `num_quads_skipped`. This is the only case where `num_quads_skipped` is incremented. Other than kSuccess and kFiailVisible, it sets specific DelegationStatue to `delegated_status_` for each [here](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/overlay_processor_delegated.cc;l=236-284;drc=e3c808e5986997a699f7fd4ed59bc5686276d9c5). Let's check some of them. [kFailNotOverlay](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/overlay_candidate_factory.cc;l=356;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) is for the resource that is not a candidate for overlay. It checks [`is_overlay_candidate`](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/common/resources/transferable_resource.h;l=154;drc=8e78783dc1f7007bad46d657c9f332614e240fd8). [kFailColorMatrix](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/overlay_candidate_factory.cc;l=152;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) is for a quad with color conversion since currently it's not possible for HW overlay plane to conver it. TODO(elkurin): Sounds specific to HW ovberlay, maybe not required for Lacros? [kFailOpacity](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/overlay_candidate_factory.cc;l=162;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) is for a quad with non-one opacity since we don't support non-one overlay plane. Render pass quads should have the integrated opacity into final output buffers. For example, when there is a quad A overlaying a quad B and we apply the opacity, B should not be seen behind A. [kFailMaskFilterNotSupported](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/overlay_candidate_factory.cc;l=173;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) is for a quad with mask filter. Unfortunately, mask filter on shared quad cannot be delegated for now. But rounded corner can be handled. [kFailNotAcisAligned](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/overlay_candidate.h;l=48;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) is for a candidate with wired rotation that is not aligned. [kFailPriority](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/overlay_candidate_factory.cc;l=615;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) is for quad with low priority. Since there is a maximum capacity that we can overlay and [OverlayPriority](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/common/quads/texture_draw_quad.h;l=20;drc=8e78783dc1f7007bad46d657c9f332614e240fd8) is to set how the quad should be prioritized. Right now, kLow means it will never be promotted. There are other failures, but let's stop at here. After computing all candidates, it compares `candidates->size() + num_quads_skipped) != quad_list->size()`. All quad must meets kSuccess or kFailVisible. If not, whole delegated compositing will be failed. If all of them were kFailVisible or kSuccess, it [CheckOverlaySupport](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/overlay_processor_using_strategy.h;l=181;drc=8e78783dc1f7007bad46d657c9f332614e240fd8). If any of `candidates` is `overlay_handled`, it fails with [kCompositedCheckOverlayFail](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/overlay_processor_delegated.h;l=79;drc=8e78783dc1f7007bad46d657c9f332614e240fd8). Finally, we successed with [kFullDelegation](https://source.chromium.org/chromium/chromium/src/+/main:components/viz/service/display/overlay_processor_delegated.h;l=76;drc=8e78783dc1f7007bad46d657c9f332614e240fd8), ## My thought Looks like some failure seems not so important to make whole render pass fails delegated compositing? Need more investigation.