Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a4b3a10e authored by Vishnu Nair's avatar Vishnu Nair
Browse files

Update output's dirty region when content changes

Correctly track content changes and update the output's dirty
region. The region is used to update the virtual display
contents. If the changes are not tracked, we may fail to update
the virtual display surface. Fix by tracking the content changes
at the layer as well as accounting for inherited parent layer
changes.

Flag: EXEMPT bugfix
Test: atest com.google.android.gts.cast.VirtualDisplayHostTest#testTestActivityEmbeddingOnVirtualDisplay  --rerun-until-failure
Bug: 360050020, 338403827
Change-Id: Iea4d8bbf0e5d478e908daafb10d13432d524da77
parent 7ed019e0
Loading
Loading
Loading
Loading
+4 −2
Original line number Original line Diff line number Diff line
@@ -250,6 +250,7 @@ std::string LayerSnapshot::getIsVisibleReason() const {
    if (drawShadows()) reason << " shadowSettings.length=" << shadowSettings.length;
    if (drawShadows()) reason << " shadowSettings.length=" << shadowSettings.length;
    if (backgroundBlurRadius > 0) reason << " backgroundBlurRadius=" << backgroundBlurRadius;
    if (backgroundBlurRadius > 0) reason << " backgroundBlurRadius=" << backgroundBlurRadius;
    if (blurRegions.size() > 0) reason << " blurRegions.size()=" << blurRegions.size();
    if (blurRegions.size() > 0) reason << " blurRegions.size()=" << blurRegions.size();
    if (contentDirty) reason << " contentDirty";
    return reason.str();
    return reason.str();
}
}


@@ -359,8 +360,9 @@ void LayerSnapshot::merge(const RequestedLayerState& requested, bool forceUpdate
                          uint32_t displayRotationFlags) {
                          uint32_t displayRotationFlags) {
    clientChanges = requested.what;
    clientChanges = requested.what;
    changes = requested.changes;
    changes = requested.changes;
    contentDirty = requested.what & layer_state_t::CONTENT_DIRTY;
    autoRefresh = requested.autoRefresh;
    hasReadyFrame = requested.autoRefresh;
    contentDirty = requested.what & layer_state_t::CONTENT_DIRTY || autoRefresh;
    hasReadyFrame = autoRefresh;
    sidebandStreamHasFrame = requested.hasSidebandStreamFrame();
    sidebandStreamHasFrame = requested.hasSidebandStreamFrame();
    updateSurfaceDamage(requested, requested.hasReadyFrame(), forceFullDamage, surfaceDamage);
    updateSurfaceDamage(requested, requested.hasReadyFrame(), forceFullDamage, surfaceDamage);


+1 −0
Original line number Original line Diff line number Diff line
@@ -77,6 +77,7 @@ struct LayerSnapshot : public compositionengine::LayerFECompositionState {
    gui::LayerMetadata layerMetadata;
    gui::LayerMetadata layerMetadata;
    gui::LayerMetadata relativeLayerMetadata;
    gui::LayerMetadata relativeLayerMetadata;
    bool hasReadyFrame; // used in post composition to check if there is another frame ready
    bool hasReadyFrame; // used in post composition to check if there is another frame ready
    bool autoRefresh;
    ui::Transform localTransformInverse;
    ui::Transform localTransformInverse;
    gui::WindowInfo inputInfo;
    gui::WindowInfo inputInfo;
    ui::Transform localTransform;
    ui::Transform localTransform;
+5 −3
Original line number Original line Diff line number Diff line
@@ -314,8 +314,8 @@ void updateMetadataAndGameMode(LayerSnapshot& snapshot, const RequestedLayerStat
void clearChanges(LayerSnapshot& snapshot) {
void clearChanges(LayerSnapshot& snapshot) {
    snapshot.changes.clear();
    snapshot.changes.clear();
    snapshot.clientChanges = 0;
    snapshot.clientChanges = 0;
    snapshot.contentDirty = false;
    snapshot.contentDirty = snapshot.autoRefresh;
    snapshot.hasReadyFrame = false;
    snapshot.hasReadyFrame = snapshot.autoRefresh;
    snapshot.sidebandStreamHasFrame = false;
    snapshot.sidebandStreamHasFrame = false;
    snapshot.surfaceDamage.clear();
    snapshot.surfaceDamage.clear();
}
}
@@ -724,10 +724,12 @@ void LayerSnapshotBuilder::updateSnapshot(LayerSnapshot& snapshot, const Args& a
    if (args.displayChanges) snapshot.changes |= RequestedLayerState::Changes::Geometry;
    if (args.displayChanges) snapshot.changes |= RequestedLayerState::Changes::Geometry;
    snapshot.reachablilty = LayerSnapshot::Reachablilty::Reachable;
    snapshot.reachablilty = LayerSnapshot::Reachablilty::Reachable;
    snapshot.clientChanges |= (parentSnapshot.clientChanges & layer_state_t::AFFECTS_CHILDREN);
    snapshot.clientChanges |= (parentSnapshot.clientChanges & layer_state_t::AFFECTS_CHILDREN);
    // mark the content as dirty if the parent state changes can dirty the child's content (for
    // example alpha)
    snapshot.contentDirty |= (snapshot.clientChanges & layer_state_t::CONTENT_DIRTY) != 0;
    snapshot.isHiddenByPolicyFromParent = parentSnapshot.isHiddenByPolicyFromParent ||
    snapshot.isHiddenByPolicyFromParent = parentSnapshot.isHiddenByPolicyFromParent ||
            parentSnapshot.invalidTransform || requested.isHiddenByPolicy() ||
            parentSnapshot.invalidTransform || requested.isHiddenByPolicy() ||
            (args.excludeLayerIds.find(path.id) != args.excludeLayerIds.end());
            (args.excludeLayerIds.find(path.id) != args.excludeLayerIds.end());

    const bool forceUpdate = args.forceUpdate == ForceUpdateFlags::ALL ||
    const bool forceUpdate = args.forceUpdate == ForceUpdateFlags::ALL ||
            snapshot.clientChanges & layer_state_t::eReparent ||
            snapshot.clientChanges & layer_state_t::eReparent ||
            snapshot.changes.any(RequestedLayerState::Changes::Visibility |
            snapshot.changes.any(RequestedLayerState::Changes::Visibility |
+3 −8
Original line number Original line Diff line number Diff line
@@ -2526,17 +2526,13 @@ bool SurfaceFlinger::updateLayerSnapshots(VsyncId vsyncId, nsecs_t frameTimeNs,
        frontend::LayerSnapshot* snapshot = mLayerSnapshotBuilder.getSnapshot(it->second->sequence);
        frontend::LayerSnapshot* snapshot = mLayerSnapshotBuilder.getSnapshot(it->second->sequence);
        gui::GameMode gameMode = (snapshot) ? snapshot->gameMode : gui::GameMode::Unsupported;
        gui::GameMode gameMode = (snapshot) ? snapshot->gameMode : gui::GameMode::Unsupported;
        mLayersWithQueuedFrames.emplace(it->second, gameMode);
        mLayersWithQueuedFrames.emplace(it->second, gameMode);
        mLayersIdsWithQueuedFrames.emplace(it->second->sequence);
    }
    }


    updateLayerHistory(latchTime);
    updateLayerHistory(latchTime);
    mLayerSnapshotBuilder.forEachSnapshot([&](const frontend::LayerSnapshot& snapshot) {
    mLayerSnapshotBuilder.forEachSnapshot([&](const frontend::LayerSnapshot& snapshot) {
        // update output dirty region if we have a queued buffer that is visible or a snapshot
        // update output's dirty region if a snapshot is visible and its
        // recently became invisible
        // content is dirty or if a snapshot recently became invisible
        // TODO(b/360050020) investigate if we need to update dirty region when layer color changes
        if ((snapshot.isVisible && snapshot.contentDirty) ||
        if ((snapshot.isVisible &&
             (mLayersIdsWithQueuedFrames.find(snapshot.path.id) !=
              mLayersIdsWithQueuedFrames.end())) ||
            (!snapshot.isVisible && snapshot.changes.test(Changes::Visibility))) {
            (!snapshot.isVisible && snapshot.changes.test(Changes::Visibility))) {
            Region visibleReg;
            Region visibleReg;
            visibleReg.set(snapshot.transformedBoundsWithoutTransparentRegion);
            visibleReg.set(snapshot.transformedBoundsWithoutTransparentRegion);
@@ -2926,7 +2922,6 @@ CompositeResultsPerDisplay SurfaceFlinger::composite(
    mScheduler->modulateVsync({}, &VsyncModulator::onDisplayRefresh, hasGpuUseOrReuse);
    mScheduler->modulateVsync({}, &VsyncModulator::onDisplayRefresh, hasGpuUseOrReuse);


    mLayersWithQueuedFrames.clear();
    mLayersWithQueuedFrames.clear();
    mLayersIdsWithQueuedFrames.clear();
    doActiveLayersTracingIfNeeded(true, mVisibleRegionsDirty, pacesetterTarget.frameBeginTime(),
    doActiveLayersTracingIfNeeded(true, mVisibleRegionsDirty, pacesetterTarget.frameBeginTime(),
                                  vsyncId);
                                  vsyncId);


+0 −1
Original line number Original line Diff line number Diff line
@@ -1253,7 +1253,6 @@ private:
    // latched.
    // latched.
    std::unordered_set<std::pair<sp<Layer>, gui::GameMode>, LayerIntHash> mLayersWithQueuedFrames;
    std::unordered_set<std::pair<sp<Layer>, gui::GameMode>, LayerIntHash> mLayersWithQueuedFrames;
    std::unordered_set<sp<Layer>, SpHash<Layer>> mLayersWithBuffersRemoved;
    std::unordered_set<sp<Layer>, SpHash<Layer>> mLayersWithBuffersRemoved;
    std::unordered_set<uint32_t> mLayersIdsWithQueuedFrames;


    // Sorted list of layers that were composed during previous frame. This is used to
    // Sorted list of layers that were composed during previous frame. This is used to
    // avoid an expensive traversal of the layer hierarchy when there are no
    // avoid an expensive traversal of the layer hierarchy when there are no
Loading