Merge "SF: Enable HWC composition strategy prediction" into tm-dev
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 700940a..b1e17b7 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -57,6 +57,7 @@
using android::base::testing::HasValue;
using android::base::testing::Ok;
using testing::ExplainMatchResult;
+using testing::Matcher;
using testing::Not;
using testing::WithParamInterface;
@@ -1258,12 +1259,23 @@
class BinderLibRpcTest : public BinderLibRpcTestBase {};
+// e.g. EXPECT_THAT(expr, Debuggable(StatusEq(...))
+// If device is debuggable AND not on user builds, expects matcher.
+// Otherwise expects INVALID_OPERATION.
+// Debuggable + non user builds is necessary but not sufficient for setRpcClientDebug to work.
+static Matcher<status_t> Debuggable(const Matcher<status_t> &matcher) {
+ bool isDebuggable = android::base::GetBoolProperty("ro.debuggable", false) &&
+ android::base::GetProperty("ro.build.type", "") != "user";
+ return isDebuggable ? matcher : StatusEq(INVALID_OPERATION);
+}
+
TEST_F(BinderLibRpcTest, SetRpcClientDebug) {
auto binder = addServer();
ASSERT_TRUE(binder != nullptr);
auto [socket, port] = CreateSocket();
ASSERT_TRUE(socket.ok());
- EXPECT_THAT(binder->setRpcClientDebug(std::move(socket), sp<BBinder>::make()), StatusEq(OK));
+ EXPECT_THAT(binder->setRpcClientDebug(std::move(socket), sp<BBinder>::make()),
+ Debuggable(StatusEq(OK)));
}
// Tests for multiple RpcServer's on the same binder object.
@@ -1274,12 +1286,14 @@
auto [socket1, port1] = CreateSocket();
ASSERT_TRUE(socket1.ok());
auto keepAliveBinder1 = sp<BBinder>::make();
- EXPECT_THAT(binder->setRpcClientDebug(std::move(socket1), keepAliveBinder1), StatusEq(OK));
+ EXPECT_THAT(binder->setRpcClientDebug(std::move(socket1), keepAliveBinder1),
+ Debuggable(StatusEq(OK)));
auto [socket2, port2] = CreateSocket();
ASSERT_TRUE(socket2.ok());
auto keepAliveBinder2 = sp<BBinder>::make();
- EXPECT_THAT(binder->setRpcClientDebug(std::move(socket2), keepAliveBinder2), StatusEq(OK));
+ EXPECT_THAT(binder->setRpcClientDebug(std::move(socket2), keepAliveBinder2),
+ Debuggable(StatusEq(OK)));
}
// Negative tests for RPC APIs on IBinder. Call should fail in the same way on both remote and
@@ -1298,7 +1312,7 @@
auto binder = GetService();
ASSERT_TRUE(binder != nullptr);
EXPECT_THAT(binder->setRpcClientDebug(android::base::unique_fd(), sp<BBinder>::make()),
- StatusEq(BAD_VALUE));
+ Debuggable(StatusEq(BAD_VALUE)));
}
TEST_P(BinderLibRpcTestP, SetRpcClientDebugNoKeepAliveBinder) {
@@ -1306,7 +1320,8 @@
ASSERT_TRUE(binder != nullptr);
auto [socket, port] = CreateSocket();
ASSERT_TRUE(socket.ok());
- EXPECT_THAT(binder->setRpcClientDebug(std::move(socket), nullptr), StatusEq(UNEXPECTED_NULL));
+ EXPECT_THAT(binder->setRpcClientDebug(std::move(socket), nullptr),
+ Debuggable(StatusEq(UNEXPECTED_NULL)));
}
INSTANTIATE_TEST_CASE_P(BinderLibTest, BinderLibRpcTestP, testing::Bool(),
BinderLibRpcTestP::ParamToString);
diff --git a/libs/ui/Transform.cpp b/libs/ui/Transform.cpp
index b34d906..42dd85e 100644
--- a/libs/ui/Transform.cpp
+++ b/libs/ui/Transform.cpp
@@ -134,6 +134,10 @@
return mMatrix[1][1];
}
+float Transform::det() const {
+ return mMatrix[0][0] * mMatrix[1][1] - mMatrix[0][1] * mMatrix[1][0];
+}
+
float Transform::getScaleX() const {
return sqrt((dsdx() * dsdx()) + (dtdx() * dtdx()));
}
@@ -390,7 +394,7 @@
const float x = M[2][0];
const float y = M[2][1];
- const float idet = 1.0f / (a*d - b*c);
+ const float idet = 1.0f / det();
result.mMatrix[0][0] = d*idet;
result.mMatrix[0][1] = -c*idet;
result.mMatrix[1][0] = -b*idet;
diff --git a/libs/ui/include/ui/Transform.h b/libs/ui/include/ui/Transform.h
index 33fbe05..f1178ca 100644
--- a/libs/ui/include/ui/Transform.h
+++ b/libs/ui/include/ui/Transform.h
@@ -77,6 +77,7 @@
float dtdx() const;
float dtdy() const;
float dsdy() const;
+ float det() const;
float getScaleX() const;
float getScaleY() const;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 533acfd..4de8dc2 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -338,6 +338,12 @@
// Calculate effective layer transform
mEffectiveTransform = parentTransform * getActiveTransform(s);
+ if (CC_UNLIKELY(!isTransformValid())) {
+ ALOGW("Stop computing bounds for %s because it has invalid transformation.",
+ getDebugName());
+ return;
+ }
+
// Transform parent bounds to layer space
parentBounds = getActiveTransform(s).inverse().transform(parentBounds);
@@ -1326,6 +1332,10 @@
}
}
}
+ if (CC_UNLIKELY(!isTransformValid())) {
+ ALOGW("Hide layer %s because it has invalid transformation.", getDebugName());
+ return true;
+ }
return s.flags & layer_state_t::eLayerHidden;
}
@@ -1858,6 +1868,11 @@
return mEffectiveTransform;
}
+bool Layer::isTransformValid() const {
+ float transformDet = getTransform().det();
+ return transformDet != 0 && !isinf(transformDet) && !isnan(transformDet);
+}
+
half Layer::getAlpha() const {
const auto& p = mDrawingParent.promote();
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 21dd5f4..2b5e337 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -752,6 +752,7 @@
FrameEventHistoryDelta* outDelta);
ui::Transform getTransform() const;
+ bool isTransformValid() const;
// Returns the Alpha of the Surface, accounting for the Alpha
// of parent Surfaces in the hierarchy (alpha's will be multiplied
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index c581a90..e8034de 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2603,6 +2603,13 @@
// Find the largest width and height among all the displays.
int32_t maxDisplayWidth = 0;
int32_t maxDisplayHeight = 0;
+
+ // If there are no displays, set a valid display bounds so we can still compute a valid layer
+ // bounds.
+ if (ON_MAIN_THREAD(mDisplays.size()) == 0) {
+ maxDisplayWidth = maxDisplayHeight = 5000;
+ }
+
for (const auto& pair : ON_MAIN_THREAD(mDisplays)) {
const auto& displayDevice = pair.second;
int32_t width = displayDevice->getWidth();
diff --git a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
index 947fdce..cf44eff 100644
--- a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
+++ b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
@@ -204,8 +204,7 @@
mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer));
mFlinger.mutableMaxRenderTargetSize() = 16384;
- flinger->setLayerTracingFlags(LayerTracing::TRACE_BUFFERS | LayerTracing::TRACE_INPUT |
- LayerTracing::TRACE_BUFFERS);
+ flinger->setLayerTracingFlags(LayerTracing::TRACE_INPUT | LayerTracing::TRACE_BUFFERS);
flinger->startLayerTracing(traceFile.entry(0).elapsed_realtime_nanos());
std::unique_ptr<TraceGenFlingerDataMapper> mapper =
std::make_unique<TraceGenFlingerDataMapper>();