[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;
};