diff options
-rw-r--r-- | libs/gui/LayerState.cpp | 89 | ||||
-rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 1 | ||||
-rw-r--r-- | libs/gui/include/gui/LayerState.h | 30 |
3 files changed, 120 insertions, 0 deletions
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index 924e65ec4a..95962afda1 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -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; } diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index d18d22d8ee..1e43700d06 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -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; } diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h index 09f171db04..6ec6bd70db 100644 --- a/libs/gui/include/gui/LayerState.h +++ b/libs/gui/include/gui/LayerState.h @@ -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; |