StretchEffect changes

Bug: 179047472
Test: StretchySurfaceViewActivity in HwAccelerationTests
Change-Id: Ia1fcd6136a380bb7099fae08ceb024eae4f79ac8
diff --git a/libs/gui/LayerDebugInfo.cpp b/libs/gui/LayerDebugInfo.cpp
index cdde9a2..e707684 100644
--- a/libs/gui/LayerDebugInfo.cpp
+++ b/libs/gui/LayerDebugInfo.cpp
@@ -61,6 +61,7 @@
     RETURN_ON_ERROR(parcel->writeBool(mRefreshPending));
     RETURN_ON_ERROR(parcel->writeBool(mIsOpaque));
     RETURN_ON_ERROR(parcel->writeBool(mContentDirty));
+    RETURN_ON_ERROR(parcel->write(mStretchEffect));
     return NO_ERROR;
 }
 
@@ -105,6 +106,7 @@
     RETURN_ON_ERROR(parcel->readBool(&mRefreshPending));
     RETURN_ON_ERROR(parcel->readBool(&mIsOpaque));
     RETURN_ON_ERROR(parcel->readBool(&mContentDirty));
+    RETURN_ON_ERROR(parcel->read(mStretchEffect));
     return NO_ERROR;
 }
 
@@ -115,6 +117,12 @@
     info.mTransparentRegion.dump(result, "TransparentRegion");
     info.mVisibleRegion.dump(result, "VisibleRegion");
     info.mSurfaceDamageRegion.dump(result, "SurfaceDamageRegion");
+    if (info.mStretchEffect.hasEffect()) {
+        const auto& se = info.mStretchEffect;
+        StringAppendF(&result, "  StretchEffect area=[%f, %f, %f, %f] vec=(%f, %f) maxAmount=%f\n",
+                      se.area.left, se.area.top, se.area.right, se.area.bottom, se.vectorX,
+                      se.vectorY, se.maxAmount);
+    }
 
     StringAppendF(&result, "      layerStack=%4d, z=%9d, pos=(%g,%g), size=(%4d,%4d), ",
                   info.mLayerStack, info.mZ, static_cast<double>(info.mX),
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index f053372..288bf92 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -548,6 +548,10 @@
         what |= eAutoRefreshChanged;
         autoRefresh = other.autoRefresh;
     }
+    if (other.what & eStretchChanged) {
+        what |= eStretchChanged;
+        stretchEffect = other.stretchEffect;
+    }
     if ((other.what & what) != other.what) {
         ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating? "
               "other.what=0x%" PRIu64 " what=0x%" PRIu64,
diff --git a/libs/gui/include/gui/LayerDebugInfo.h b/libs/gui/include/gui/LayerDebugInfo.h
index 66a7b4d..8b7d32c 100644
--- a/libs/gui/include/gui/LayerDebugInfo.h
+++ b/libs/gui/include/gui/LayerDebugInfo.h
@@ -20,6 +20,7 @@
 
 #include <ui/PixelFormat.h>
 #include <ui/Region.h>
+#include <ui/StretchEffect.h>
 
 #include <string>
 #include <math/vec4.h>
@@ -66,6 +67,7 @@
     bool mRefreshPending = false;
     bool mIsOpaque = false;
     bool mContentDirty = false;
+    StretchEffect mStretchEffect = {};
 };
 
 std::string to_string(const LayerDebugInfo& info);
diff --git a/libs/ui/include/ui/FloatRect.h b/libs/ui/include/ui/FloatRect.h
index bec2552..5d329ea 100644
--- a/libs/ui/include/ui/FloatRect.h
+++ b/libs/ui/include/ui/FloatRect.h
@@ -48,6 +48,8 @@
     float top = 0.0f;
     float right = 0.0f;
     float bottom = 0.0f;
+
+    constexpr bool isEmpty() const { return !(left < right && top < bottom); }
 };
 
 inline bool operator==(const FloatRect& a, const FloatRect& b) {
diff --git a/libs/ui/include/ui/StretchEffect.h b/libs/ui/include/ui/StretchEffect.h
index 1d2460c..0803df3 100644
--- a/libs/ui/include/ui/StretchEffect.h
+++ b/libs/ui/include/ui/StretchEffect.h
@@ -19,6 +19,7 @@
 #include <utils/Flattenable.h>
 #include "FloatRect.h"
 
+#include <math.h>
 #include <type_traits>
 
 namespace android {
@@ -45,7 +46,7 @@
 
     void sanitize() {
         // If the area is empty, or the max amount is zero, then reset back to defaults
-        if (area.bottom >= area.top || area.left >= area.right || isZero(maxAmount)) {
+        if (area.isEmpty() || isZero(maxAmount)) {
             *this = StretchEffect{};
         }
     }
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/DumpHelpers.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/DumpHelpers.h
index 782c8d7..6b9597b 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/DumpHelpers.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/DumpHelpers.h
@@ -24,6 +24,7 @@
 #include <ui/FloatRect.h>
 #include <ui/Rect.h>
 #include <ui/Region.h>
+#include <ui/StretchEffect.h>
 #include <ui/Transform.h>
 
 namespace android::compositionengine::impl {
@@ -58,5 +59,6 @@
 void dumpVal(std::string& out, const char* name, const ui::Size&);
 
 void dumpVal(std::string& out, const char* name, const mat4& tr);
+void dumpVal(std::string& out, const char* name, const StretchEffect&);
 
 } // namespace android::compositionengine::impl
diff --git a/services/surfaceflinger/CompositionEngine/src/DumpHelpers.cpp b/services/surfaceflinger/CompositionEngine/src/DumpHelpers.cpp
index 9d1bb02..0cc2c6e 100644
--- a/services/surfaceflinger/CompositionEngine/src/DumpHelpers.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/DumpHelpers.cpp
@@ -100,4 +100,10 @@
                   ); /* clang-format on */
 }
 
+void dumpVal(std::string& out, const char* name, const StretchEffect& effect) {
+    StringAppendF(&out, "%s={ area=[%f, %f, %f, %f], vec=(%f, %f), max=%f } ", name,
+                  effect.area.left, effect.area.top, effect.area.right, effect.area.bottom,
+                  effect.vectorX, effect.vectorY, effect.maxAmount);
+}
+
 } // namespace android::compositionengine::impl
diff --git a/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp b/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp
index 1338538..430945a 100644
--- a/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/LayerFECompositionState.cpp
@@ -74,6 +74,9 @@
     dumpVal(out, "blend", toString(blendMode), blendMode);
     dumpVal(out, "alpha", alpha);
     dumpVal(out, "backgroundBlurRadius", backgroundBlurRadius);
+    if (stretchEffect.hasEffect()) {
+        dumpVal(out, "stretchEffect", stretchEffect);
+    }
 
     if (!metadata.empty()) {
         out.append("\n      metadata {");
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 237aaff..cc7b2e7 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -488,7 +488,7 @@
     compositionState->alpha = alpha;
     compositionState->backgroundBlurRadius = drawingState.backgroundBlurRadius;
     compositionState->blurRegions = drawingState.blurRegions;
-    compositionState->stretchEffect = drawingState.stretchEffect;
+    compositionState->stretchEffect = getStretchEffect();
 }
 
 void Layer::prepareGeometryCompositionState() {
@@ -558,7 +558,7 @@
 
     // Force client composition for special cases known only to the front-end.
     if (isHdrY410() || usesRoundedCorners || drawShadows() || drawingState.blurRegions.size() > 0 ||
-        drawingState.stretchEffect.hasEffect()) {
+        compositionState->stretchEffect.hasEffect()) {
         compositionState->forceClientComposition = true;
     }
 }
@@ -1436,6 +1436,22 @@
     return true;
 }
 
+StretchEffect Layer::getStretchEffect() const {
+    if (mDrawingState.stretchEffect.hasEffect()) {
+        return mDrawingState.stretchEffect;
+    }
+
+    sp<Layer> parent = getParent();
+    if (parent != nullptr) {
+        auto effect = parent->getStretchEffect();
+        if (effect.hasEffect()) {
+            // TODO(b/179047472): Map it? Or do we make the effect be in global space?
+            return effect;
+        }
+    }
+    return StretchEffect{};
+}
+
 void Layer::updateTreeHasFrameRateVote() {
     const auto traverseTree = [&](const LayerVector::Visitor& visitor) {
         auto parent = getParent();
@@ -1740,6 +1756,7 @@
     info.mRefreshPending = isBufferLatched();
     info.mIsOpaque = isOpaque(ds);
     info.mContentDirty = contentDirty;
+    info.mStretchEffect = getStretchEffect();
     return info;
 }
 
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 687f473..f87aec2 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -943,6 +943,7 @@
     bool backpressureEnabled() { return mDrawingState.flags & layer_state_t::eEnableBackpressure; }
 
     bool setStretchEffect(const StretchEffect& effect);
+    StretchEffect getStretchEffect() const;
 
 protected:
     class SyncPoint {
diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp
index 61005c9..b0413f1 100644
--- a/services/surfaceflinger/SurfaceInterceptor.cpp
+++ b/services/surfaceflinger/SurfaceInterceptor.cpp
@@ -499,6 +499,9 @@
     if (state.what & layer_state_t::eShadowRadiusChanged) {
         addShadowRadiusLocked(transaction, layerId, state.shadowRadius);
     }
+    if (state.what & layer_state_t::eStretchChanged) {
+        ALOGW("SurfaceInterceptor not implemented for eStretchChanged");
+    }
 }
 
 void SurfaceInterceptor::addDisplayChangesLocked(Transaction* transaction,