[Shadows] Set shadow settings per layer (5/n)

- Save global shadow settings set by WindowManager
- Add ShadowSettings to renderengine per layer rendering info

Bug: 136561771
Test: go/wm-smoke
Change-Id: I89cf84c7e089273ae3edea02e2ac24690055ba47
diff --git a/libs/renderengine/include/renderengine/LayerSettings.h b/libs/renderengine/include/renderengine/LayerSettings.h
index b8bf801..b851d5c 100644
--- a/libs/renderengine/include/renderengine/LayerSettings.h
+++ b/libs/renderengine/include/renderengine/LayerSettings.h
@@ -96,6 +96,33 @@
     half3 solidColor = half3(0.0f, 0.0f, 0.0f);
 };
 
+/*
+ * Contains the configuration for the shadows drawn by single layer. Shadow follows
+ * material design guidelines.
+ */
+struct ShadowSettings {
+    // Color to the ambient shadow. The alpha is premultiplied.
+    vec4 ambientColor = vec4();
+
+    // Color to the spot shadow. The alpha is premultiplied. The position of the spot shadow
+    // depends on the light position.
+    vec4 spotColor = vec4();
+
+    // Position of the light source used to cast the spot shadow.
+    vec3 lightPos = vec3();
+
+    // Radius of the spot light source. Smaller radius will have sharper edges,
+    // larger radius will have softer shadows
+    float lightRadius = 0.f;
+
+    // Length of the cast shadow. If length is <= 0.f no shadows will be drawn.
+    float length = 0.f;
+
+    // If true fill in the casting layer is translucent and the shadow needs to fill the bounds.
+    // Otherwise the shadow will only be drawn around the edges of the casting layer.
+    bool casterIsTranslucent = false;
+};
+
 // The settings that RenderEngine requires for correctly rendering a Layer.
 struct LayerSettings {
     // Geometry information
@@ -116,6 +143,8 @@
 
     // True if blending will be forced to be disabled.
     bool disableBlending = false;
+
+    ShadowSettings shadow;
 };
 
 } // namespace renderengine
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index ce9aab5..3d00352 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1800,6 +1800,18 @@
             : RoundedCornerState();
 }
 
+renderengine::ShadowSettings Layer::getShadowSettings(const Rect& viewport) const {
+    renderengine::ShadowSettings state = mFlinger->mDrawingState.globalShadowSettings;
+
+    // Shift the spot light x-position to the middle of the display and then
+    // offset it by casting layer's screen pos.
+    state.lightPos.x = (viewport.width() / 2.f) - mScreenBounds.left;
+    state.lightPos.y -= mScreenBounds.top;
+
+    state.length = mEffectiveShadowRadius;
+    return state;
+}
+
 void Layer::commitChildList() {
     for (size_t i = 0; i < mCurrentChildren.size(); i++) {
         const auto& child = mCurrentChildren[i];
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 7abcd0f..16bdb01 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -216,6 +216,9 @@
         std::deque<sp<CallbackHandle>> callbackHandles;
         bool colorSpaceAgnostic;
         nsecs_t desiredPresentTime = -1;
+
+        // Length of the cast shadow. If the radius is > 0, a shadow of length shadowRadius will
+        // be rendered around the layer.
         float shadowRadius;
     };
 
@@ -650,6 +653,8 @@
     // ignored.
     RoundedCornerState getRoundedCornerState() const;
 
+    renderengine::ShadowSettings getShadowSettings(const Rect& viewport) const;
+
     void traverseInReverseZOrder(LayerVector::StateSet stateSet,
                                  const LayerVector::Visitor& visitor);
     void traverseInZOrder(LayerVector::StateSet stateSet, const LayerVector::Visitor& visitor);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index c555f79..682932b 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -5512,9 +5512,19 @@
     getRenderEngine().unbindExternalTextureBuffer(clientCacheId.id);
 }
 
-status_t SurfaceFlinger::setGlobalShadowSettings(const half4& /*ambientColor*/,
-                                                 const half4& /*spotColor*/, float /*lightPosY*/,
-                                                 float /*lightPosZ*/, float /*lightRadius*/) {
+status_t SurfaceFlinger::setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor,
+                                                 float lightPosY, float lightPosZ,
+                                                 float lightRadius) {
+    Mutex::Autolock _l(mStateLock);
+    mCurrentState.globalShadowSettings.ambientColor = vec4(ambientColor);
+    mCurrentState.globalShadowSettings.spotColor = vec4(spotColor);
+    mCurrentState.globalShadowSettings.lightPos.y = lightPosY;
+    mCurrentState.globalShadowSettings.lightPos.z = lightPosZ;
+    mCurrentState.globalShadowSettings.lightRadius = lightRadius;
+
+    // these values are overridden when calculating the shadow settings for a layer.
+    mCurrentState.globalShadowSettings.lightPos.x = 0.f;
+    mCurrentState.globalShadowSettings.length = 0.f;
     return NO_ERROR;
 }
 
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 5b1853c..a5cd689 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -37,6 +37,7 @@
 #include <input/ISetInputWindowsListener.h>
 #include <layerproto/LayerProtoHeader.h>
 #include <math/mat4.h>
+#include <renderengine/LayerSettings.h>
 #include <serviceutils/PriorityDumper.h>
 #include <system/graphics.h>
 #include <ui/FenceTime.h>
@@ -365,6 +366,8 @@
             if (colorMatrixChanged) {
                 colorMatrix = other.colorMatrix;
             }
+            globalShadowSettings = other.globalShadowSettings;
+
             return *this;
         }
 
@@ -375,6 +378,8 @@
         bool colorMatrixChanged = true;
         mat4 colorMatrix;
 
+        renderengine::ShadowSettings globalShadowSettings;
+
         void traverseInZOrder(const LayerVector::Visitor& visitor) const;
         void traverseInReverseZOrder(const LayerVector::Visitor& visitor) const;
     };