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

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

libgui: add layer_state_t::diff

Compares two layer_state_t structs and returns
a set of change flags describing all the states
that are different.

Also introduces change sets describing which
set of client states can affect the hierarchy,
content or the content size.

Bug: 238781169
Test: presubmit
Change-Id: I6e5fb255972aff2373be27e62005ee3a8de7ebf6
parent d1c4b8ab
Loading
Loading
Loading
Loading
+89 −0
Original line number Diff line number Diff line
@@ -24,10 +24,31 @@
#include <binder/Parcel.h>
#include <gui/IGraphicBufferProducer.h>
#include <gui/LayerState.h>
#include <gui/SurfaceControl.h>
#include <private/gui/ParcelUtils.h>
#include <system/window.h>
#include <utils/Errors.h>

#define CHECK_DIFF(DIFF_RESULT, CHANGE_FLAG, OTHER, FIELD)          \
    {                                                               \
        if ((OTHER.what & CHANGE_FLAG) && (FIELD != OTHER.FIELD)) { \
            DIFF_RESULT |= CHANGE_FLAG;                             \
        }                                                           \
    }

#define CHECK_DIFF2(DIFF_RESULT, CHANGE_FLAG, OTHER, FIELD1, FIELD2) \
    {                                                                \
        CHECK_DIFF(DIFF_RESULT, CHANGE_FLAG, OTHER, FIELD1)          \
        CHECK_DIFF(DIFF_RESULT, CHANGE_FLAG, OTHER, FIELD2)          \
    }

#define CHECK_DIFF3(DIFF_RESULT, CHANGE_FLAG, OTHER, FIELD1, FIELD2, FIELD3) \
    {                                                                        \
        CHECK_DIFF(DIFF_RESULT, CHANGE_FLAG, OTHER, FIELD1)                  \
        CHECK_DIFF(DIFF_RESULT, CHANGE_FLAG, OTHER, FIELD2)                  \
        CHECK_DIFF(DIFF_RESULT, CHANGE_FLAG, OTHER, FIELD3)                  \
    }

namespace android {

using gui::FocusRequest;
@@ -626,6 +647,74 @@ void layer_state_t::merge(const layer_state_t& other) {
    }
}

uint64_t layer_state_t::diff(const layer_state_t& other) const {
    uint64_t diff = 0;
    CHECK_DIFF2(diff, ePositionChanged, other, x, y);
    if (other.what & eLayerChanged) {
        diff |= eLayerChanged;
        diff &= ~eRelativeLayerChanged;
    }
    CHECK_DIFF(diff, eAlphaChanged, other, color.a);
    CHECK_DIFF(diff, eMatrixChanged, other, matrix);
    if (other.what & eTransparentRegionChanged &&
        (!transparentRegion.hasSameRects(other.transparentRegion))) {
        diff |= eTransparentRegionChanged;
    }
    if (other.what & eFlagsChanged) {
        uint64_t changedFlags = (flags & other.mask) ^ (other.flags & other.mask);
        if (changedFlags) diff |= eFlagsChanged;
    }
    CHECK_DIFF(diff, eLayerStackChanged, other, layerStack);
    CHECK_DIFF(diff, eCornerRadiusChanged, other, cornerRadius);
    CHECK_DIFF(diff, eBackgroundBlurRadiusChanged, other, backgroundBlurRadius);
    if (other.what & eBlurRegionsChanged) diff |= eBlurRegionsChanged;
    if (other.what & eRelativeLayerChanged) {
        diff |= eRelativeLayerChanged;
        diff &= ~eLayerChanged;
    }
    if (other.what & eReparent &&
        !SurfaceControl::isSameSurface(parentSurfaceControlForChild,
                                       other.parentSurfaceControlForChild)) {
        diff |= eReparent;
    }
    CHECK_DIFF(diff, eBufferTransformChanged, other, bufferTransform);
    CHECK_DIFF(diff, eTransformToDisplayInverseChanged, other, transformToDisplayInverse);
    CHECK_DIFF(diff, eCropChanged, other, crop);
    if (other.what & eBufferChanged) diff |= eBufferChanged;
    CHECK_DIFF(diff, eDataspaceChanged, other, dataspace);
    CHECK_DIFF(diff, eHdrMetadataChanged, other, hdrMetadata);
    if (other.what & eSurfaceDamageRegionChanged &&
        (!surfaceDamageRegion.hasSameRects(other.surfaceDamageRegion))) {
        diff |= eSurfaceDamageRegionChanged;
    }
    CHECK_DIFF(diff, eApiChanged, other, api);
    if (other.what & eSidebandStreamChanged) diff |= eSidebandStreamChanged;
    CHECK_DIFF(diff, eApiChanged, other, api);
    CHECK_DIFF(diff, eColorTransformChanged, other, colorTransform);
    if (other.what & eHasListenerCallbacksChanged) diff |= eHasListenerCallbacksChanged;
    if (other.what & eInputInfoChanged) diff |= eInputInfoChanged;
    CHECK_DIFF3(diff, eBackgroundColorChanged, other, color.rgb, bgColorAlpha, bgColorDataspace);
    if (other.what & eMetadataChanged) diff |= eMetadataChanged;
    CHECK_DIFF(diff, eShadowRadiusChanged, other, shadowRadius);
    CHECK_DIFF3(diff, eRenderBorderChanged, other, borderEnabled, borderWidth, borderColor);
    CHECK_DIFF(diff, eDefaultFrameRateCompatibilityChanged, other, defaultFrameRateCompatibility);
    CHECK_DIFF(diff, eFrameRateSelectionPriority, other, frameRateSelectionPriority);
    CHECK_DIFF3(diff, eFrameRateChanged, other, frameRate, frameRateCompatibility,
                changeFrameRateStrategy);
    CHECK_DIFF(diff, eFixedTransformHintChanged, other, fixedTransformHint);
    CHECK_DIFF(diff, eAutoRefreshChanged, other, autoRefresh);
    CHECK_DIFF(diff, eTrustedOverlayChanged, other, isTrustedOverlay);
    CHECK_DIFF(diff, eStretchChanged, other, stretchEffect);
    CHECK_DIFF(diff, eBufferCropChanged, other, bufferCrop);
    CHECK_DIFF(diff, eDestinationFrameChanged, other, destinationFrame);
    if (other.what & eProducerDisconnect) diff |= eProducerDisconnect;
    CHECK_DIFF(diff, eDropInputModeChanged, other, dropInputMode);
    CHECK_DIFF(diff, eColorChanged, other, color.rgb);
    CHECK_DIFF(diff, eColorSpaceAgnosticChanged, other, colorSpaceAgnostic);
    CHECK_DIFF(diff, eDimmingEnabledChanged, other, dimmingEnabled);
    return diff;
}

bool layer_state_t::hasBufferChanges() const {
    return what & layer_state_t::eBufferChanged;
}
+1 −0
Original line number Diff line number Diff line
@@ -1250,6 +1250,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFlags
    if ((mask & layer_state_t::eLayerOpaque) || (mask & layer_state_t::eLayerHidden) ||
        (mask & layer_state_t::eLayerSecure) || (mask & layer_state_t::eLayerSkipScreenshot) ||
        (mask & layer_state_t::eEnableBackpressure) ||
        (mask & layer_state_t::eIgnoreDestinationFrame) ||
        (mask & layer_state_t::eLayerIsDisplayDecoration)) {
        s->what |= layer_state_t::eFlagsChanged;
    }
+30 −0
Original line number Diff line number Diff line
@@ -201,7 +201,32 @@ struct layer_state_t {
    void merge(const layer_state_t& other);
    status_t write(Parcel& output) const;
    status_t read(const Parcel& input);
    // Compares two layer_state_t structs and returns a set of change flags describing all the
    // states that are different.
    uint64_t diff(const layer_state_t& other) const;
    bool hasBufferChanges() const;

    // Changes to the tree structure.
    static constexpr uint64_t HIERARCHY_CHANGES = layer_state_t::eLayerChanged |
            layer_state_t::eRelativeLayerChanged | layer_state_t::eReparent |
            layer_state_t::eBackgroundColorChanged;
    // Content updates.
    static constexpr uint64_t CONTENT_CHANGES = layer_state_t::eAlphaChanged |
            layer_state_t::eTransparentRegionChanged | layer_state_t::eShadowRadiusChanged |
            layer_state_t::eRenderBorderChanged | layer_state_t::eColorChanged |
            layer_state_t::eBufferChanged | layer_state_t::eDataspaceChanged |
            layer_state_t::eApiChanged | layer_state_t::eSidebandStreamChanged |
            layer_state_t::eColorTransformChanged | layer_state_t::eCornerRadiusChanged |
            layer_state_t::eBackgroundColorChanged | layer_state_t::eColorSpaceAgnosticChanged |
            layer_state_t::eBackgroundBlurRadiusChanged | layer_state_t::eBlurRegionsChanged |
            layer_state_t::eAutoRefreshChanged | layer_state_t::eStretchChanged;
    // Changes to content or children size.
    static constexpr uint64_t GEOMETRY_CHANGES = layer_state_t::ePositionChanged |
            layer_state_t::eMatrixChanged | layer_state_t::eTransparentRegionChanged |
            layer_state_t::eBufferCropChanged | layer_state_t::eBufferTransformChanged |
            layer_state_t::eTransformToDisplayInverseChanged | layer_state_t::eCropChanged |
            layer_state_t::eDestinationFrameChanged;

    bool hasValidBuffer() const;
    void sanitize(int32_t permissions);

@@ -212,6 +237,11 @@ struct layer_state_t {
        float dsdy{0};
        status_t write(Parcel& output) const;
        status_t read(const Parcel& input);
        inline bool operator==(const matrix22_t& other) const {
            return std::tie(dsdx, dtdx, dtdy, dsdy) ==
                    std::tie(other.dsdx, other.dtdx, other.dtdy, other.dsdy);
        }
        inline bool operator!=(const matrix22_t& other) const { return !(*this == other); }
    };
    sp<IBinder> surface;
    int32_t layerId;