diff options
author | 2020-08-03 15:53:27 -0700 | |
---|---|---|
committer | 2020-08-14 18:47:33 +0000 | |
commit | 3cbda59fe27ef576f57f6a77def38ade410c43e4 (patch) | |
tree | 714ae23c8c28e99930c7fbb120a55ac493b40f7f | |
parent | 73dd99b7c0e3018249fe07d445c537d16345fb09 (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.h | 11 | ||||
-rw-r--r-- | libs/gui/tests/Android.bp | 26 | ||||
-rw-r--r-- | libs/gui/tests/DisplayEventStructLayout_test.cpp | 43 |
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 |