summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/Layer.cpp
diff options
context:
space:
mode:
author Lucas Dupin <dupin@google.com> 2018-07-05 17:18:21 -0700
committer Lucas Dupin <dupin@google.com> 2018-12-02 09:27:05 -0800
commit1b6531ccf5dab13a6817c7519693df220d0944a1 (patch)
tree2873750c9ee97e4bf11d557997bfe27137e16040 /services/surfaceflinger/Layer.cpp
parent49109214fec02f0734cbfee3c58f6974b0c694b2 (diff)
Rounded corners
Test: visual Test: /data/nativetest64/SurfaceFlinger_test/SurfaceFlinger_test Fixes: 111514493 Change-Id: Ie8f400bbcea3e9653295ea7b75c7eef568fd76c4
Diffstat (limited to 'services/surfaceflinger/Layer.cpp')
-rw-r--r--services/surfaceflinger/Layer.cpp50
1 files changed, 50 insertions, 0 deletions
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 81456dfea9..4080f12449 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -101,6 +101,7 @@ Layer::Layer(const LayerCreationArgs& args)
mCurrentState.dataspace = ui::Dataspace::UNKNOWN;
mCurrentState.hdrMetadata.validTypes = 0;
mCurrentState.surfaceDamageRegion.clear();
+ mCurrentState.cornerRadius = 0.0f;
mCurrentState.api = -1;
mCurrentState.hasColorTransform = false;
@@ -400,6 +401,23 @@ Rect Layer::computeInitialCrop(const sp<const DisplayDevice>& display) const {
return activeCrop;
}
+void Layer::setupRoundedCornersCropCoordinates(Rect win,
+ const FloatRect& roundedCornersCrop) const {
+ // Translate win by the rounded corners rect coordinates, to have all values in
+ // layer coordinate space.
+ win.left -= roundedCornersCrop.left;
+ win.right -= roundedCornersCrop.left;
+ win.top -= roundedCornersCrop.top;
+ win.bottom -= roundedCornersCrop.top;
+
+ renderengine::Mesh::VertexArray<vec2> cropCoords(getBE().mMesh.getCropCoordArray<vec2>());
+ cropCoords[0] = vec2(win.left, win.top);
+ cropCoords[1] = vec2(win.left, win.top + win.getHeight());
+ cropCoords[2] = vec2(win.right, win.top + win.getHeight());
+ cropCoords[3] = vec2(win.right, win.top);
+ cropCoords[3] = vec2(win.right, win.top);
+}
+
FloatRect Layer::computeCrop(const sp<const DisplayDevice>& display) const {
// the content crop is the area of the content that gets scaled to the
// layer's size. This is in buffer space.
@@ -1220,6 +1238,17 @@ bool Layer::setColor(const half3& color) {
return true;
}
+bool Layer::setCornerRadius(float cornerRadius) {
+ if (mCurrentState.cornerRadius == cornerRadius)
+ return false;
+
+ mCurrentState.sequence++;
+ mCurrentState.cornerRadius = cornerRadius;
+ mCurrentState.modified = true;
+ setTransactionFlags(eTransactionNeeded);
+ return true;
+}
+
bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix,
bool allowNonRectPreservingTransforms) {
ui::Transform t;
@@ -1918,6 +1947,26 @@ half4 Layer::getColor() const {
return half4(color.r, color.g, color.b, getAlpha());
}
+Layer::RoundedCornerState Layer::getRoundedCornerState() const {
+ const auto& p = mDrawingParent.promote();
+ if (p != nullptr) {
+ RoundedCornerState parentState = p->getRoundedCornerState();
+ if (parentState.radius > 0) {
+ ui::Transform t = getActiveTransform(getDrawingState());
+ t = t.inverse();
+ parentState.cropRect = t.transform(parentState.cropRect);
+ // The rounded corners shader only accepts 1 corner radius for performance reasons,
+ // but a transform matrix can define horizontal and vertical scales.
+ // Let's take the average between both of them and pass into the shader, practically we
+ // never do this type of transformation on windows anyway.
+ parentState.radius *= (t[0][0] + t[1][1]) / 2.0f;
+ return parentState;
+ }
+ }
+ const float radius = getDrawingState().cornerRadius;
+ return radius > 0 ? RoundedCornerState(computeBounds(), radius) : RoundedCornerState();
+}
+
void Layer::commitChildList() {
for (size_t i = 0; i < mCurrentChildren.size(); i++) {
const auto& child = mCurrentChildren[i];
@@ -1978,6 +2027,7 @@ void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet)
size->set_h(state.active_legacy.h);
LayerProtoHelper::writeToProto(state.crop_legacy, layerInfo->mutable_crop());
+ layerInfo->set_corner_radius(getRoundedCornerState().radius);
layerInfo->set_is_opaque(isOpaque(state));
layerInfo->set_invalidate(contentDirty);