summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Yahan Zhou <yahan@google.com> 2020-08-03 15:53:27 -0700
committer Yahan Zhou <yahan@google.com> 2020-08-14 18:47:33 +0000
commit3cbda59fe27ef576f57f6a77def38ade410c43e4 (patch)
tree714ae23c8c28e99930c7fbb120a55ac493b40f7f
parent73dd99b7c0e3018249fe07d445c537d16345fb09 (diff)
Align DisplayEventReceiver events
The structs are aligned differently on x86 vs x64, causing them to parse messages wrong. Test: CtsGraphicsTestCases android.graphics.drawable.cts.AnimatedImageDrawableTest#testLifeCycle Bug: 149314120 Change-Id: I745ba7647ecadffed016f1694a7b4a81c5ef195c
-rw-r--r--libs/gui/include/gui/DisplayEventReceiver.h11
-rw-r--r--libs/gui/tests/Android.bp26
-rw-r--r--libs/gui/tests/DisplayEventStructLayout_test.cpp43
3 files changed, 76 insertions, 4 deletions
diff --git a/libs/gui/include/gui/DisplayEventReceiver.h b/libs/gui/include/gui/DisplayEventReceiver.h
index 0e10d1ad8e..7974a0648c 100644
--- a/libs/gui/include/gui/DisplayEventReceiver.h
+++ b/libs/gui/include/gui/DisplayEventReceiver.h
@@ -57,16 +57,21 @@ public:
};
struct Event {
+ // We add __attribute__((aligned(8))) for nsecs_t fields because
+ // we need to make sure all fields are aligned the same with x86
+ // and x64 (long long has different default alignment):
+ //
+ // https://en.wikipedia.org/wiki/Data_structure_alignment
struct Header {
uint32_t type;
- PhysicalDisplayId displayId;
+ PhysicalDisplayId displayId __attribute__((aligned(8)));
nsecs_t timestamp __attribute__((aligned(8)));
};
struct VSync {
uint32_t count;
- nsecs_t expectedVSyncTimestamp;
+ nsecs_t expectedVSyncTimestamp __attribute__((aligned(8)));
};
struct Hotplug {
@@ -75,7 +80,7 @@ public:
struct Config {
int32_t configId;
- nsecs_t vsyncPeriod;
+ nsecs_t vsyncPeriod __attribute__((aligned(8)));
};
Header header;
diff --git a/libs/gui/tests/Android.bp b/libs/gui/tests/Android.bp
index a6bcd107af..53c13c8859 100644
--- a/libs/gui/tests/Android.bp
+++ b/libs/gui/tests/Android.bp
@@ -14,7 +14,7 @@ cc_test {
srcs: [
"BLASTBufferQueue_test.cpp",
- "BufferItemConsumer_test.cpp",
+ "BufferItemConsumer_test.cpp",
"BufferQueue_test.cpp",
"CpuConsumer_test.cpp",
"EndToEndNativeInputTest.cpp",
@@ -58,6 +58,30 @@ cc_test {
header_libs: ["libsurfaceflinger_headers"],
}
+// Build the tests that need to run with both 32bit and 64bit.
+cc_test {
+ name: "libgui_multilib_test",
+ test_suites: ["device-tests"],
+
+ clang: true,
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+
+ srcs: [
+ "DisplayEventStructLayout_test.cpp",
+ ],
+
+ shared_libs: [
+ "libgui",
+ ],
+
+ compile_multilib: "both",
+
+ header_libs: ["libsurfaceflinger_headers"],
+}
+
// Build a separate binary to $(TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE)
// This test has a main method, and requires a separate binary to be built.
// To add move tests like this, just add additional cc_test statements,
diff --git a/libs/gui/tests/DisplayEventStructLayout_test.cpp b/libs/gui/tests/DisplayEventStructLayout_test.cpp
new file mode 100644
index 0000000000..4bcb7953c6
--- /dev/null
+++ b/libs/gui/tests/DisplayEventStructLayout_test.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+#include <gui/DisplayEventReceiver.h>
+
+namespace android::test {
+
+#define CHECK_OFFSET(type, member, expected_offset) \
+ static_assert((offsetof(type, member) == (expected_offset)), "")
+
+TEST(DisplayEventStructLayoutTest, TestEventAlignment) {
+ CHECK_OFFSET(DisplayEventReceiver::Event, vsync, 24);
+ CHECK_OFFSET(DisplayEventReceiver::Event, hotplug, 24);
+ CHECK_OFFSET(DisplayEventReceiver::Event, config, 24);
+
+ CHECK_OFFSET(DisplayEventReceiver::Event::Header, type, 0);
+ CHECK_OFFSET(DisplayEventReceiver::Event::Header, displayId, 8);
+ CHECK_OFFSET(DisplayEventReceiver::Event::Header, timestamp, 16);
+
+ CHECK_OFFSET(DisplayEventReceiver::Event::VSync, count, 0);
+ CHECK_OFFSET(DisplayEventReceiver::Event::VSync, expectedVSyncTimestamp, 8);
+
+ CHECK_OFFSET(DisplayEventReceiver::Event::Hotplug, connected, 0);
+
+ CHECK_OFFSET(DisplayEventReceiver::Event::Config, configId, 0);
+ CHECK_OFFSET(DisplayEventReceiver::Event::Config, vsyncPeriod, 8);
+}
+
+} // namespace android::test