SF: Introduce a minimal CompositionEngine
Start with minimal sources for CompositionEngine, which is otherwise
blank. This sets up a library for the implementation, a library for
CompositionEngine owned test mocks, and a minimal test.
SurfaceFlinger will also create an instance via its factory, and
provides an accessor to obtain it.
Test: atest libsurfaceflinger_unittest libcompositionengine_test
Bug: 121291683
Change-Id: I4be49254d2cea82adfbafc6108891347d49d3f17
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 0106b25..1d2cdb1 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -1,7 +1,6 @@
cc_defaults {
name: "surfaceflinger_defaults",
cflags: [
- "-DLOG_TAG=\"SurfaceFlinger\"",
"-Wall",
"-Werror",
"-Wformat",
@@ -15,6 +14,7 @@
name: "libsurfaceflinger_defaults",
defaults: ["surfaceflinger_defaults"],
cflags: [
+ "-DLOG_TAG=\"SurfaceFlinger\"",
"-DGL_GLEXT_PROTOTYPES",
"-DEGL_EGLEXT_PROTOTYPES",
],
@@ -57,6 +57,7 @@
"libutils",
],
static_libs: [
+ "libcompositionengine",
"librenderengine",
"libserviceutils",
"libtrace_proto",
@@ -69,6 +70,7 @@
"android.hardware.graphics.composer@2.3-command-buffer",
],
export_static_lib_headers: [
+ "libcompositionengine",
"librenderengine",
"libserviceutils",
],
@@ -171,6 +173,9 @@
cc_defaults {
name: "libsurfaceflinger_binary",
defaults: ["surfaceflinger_defaults"],
+ cflags: [
+ "-DLOG_TAG=\"SurfaceFlinger\"",
+ ],
whole_static_libs: [
"libsigchain",
],
diff --git a/services/surfaceflinger/CompositionEngine/Android.bp b/services/surfaceflinger/CompositionEngine/Android.bp
new file mode 100644
index 0000000..9fb16a6
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/Android.bp
@@ -0,0 +1,62 @@
+cc_defaults {
+ name: "libcompositionengine_defaults",
+ defaults: ["surfaceflinger_defaults"],
+ cflags: [
+ "-DLOG_TAG=\"CompositionEngine\"",
+ ],
+}
+
+cc_library {
+ name: "libcompositionengine",
+ defaults: ["libcompositionengine_defaults"],
+ srcs: [
+ "src/CompositionEngine.cpp",
+ ],
+ local_include_dirs: ["include"],
+ export_include_dirs: ["include"],
+}
+
+cc_library {
+ name: "libcompositionengine_mocks",
+ defaults: ["libcompositionengine_defaults"],
+ srcs: [
+ "mock/CompositionEngine.cpp",
+ ],
+ static_libs: [
+ "libgtest",
+ "libgmock",
+ "libcompositionengine",
+ ],
+ local_include_dirs: ["include"],
+ export_include_dirs: ["include"],
+}
+
+cc_test {
+ name: "libcompositionengine_test",
+ test_suites: ["device-tests"],
+ defaults: ["libcompositionengine_defaults"],
+ srcs: [
+ "tests/CompositionEngineTest.cpp",
+ ],
+ static_libs: [
+ "libcompositionengine",
+ "libcompositionengine_mocks",
+ "libgmock",
+ "libgtest",
+ ],
+ sanitize: {
+ // By using the address sanitizer, we not only uncover any issues
+ // with the test, but also any issues with the code under test.
+ //
+ // Note: If you get an runtime link error like:
+ //
+ // CANNOT LINK EXECUTABLE "/data/local/tmp/libcompositionengine_test": library "libclang_rt.asan-aarch64-android.so" not found
+ //
+ // it is because the address sanitizer shared objects are not installed
+ // by default in the system image.
+ //
+ // You can either "make dist tests" before flashing, or set this
+ // option to false temporarily.
+ address: true,
+ },
+}
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h
new file mode 100644
index 0000000..275dd86
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2018 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.
+ */
+
+#pragma once
+
+namespace android {
+
+class HWComposer;
+
+namespace compositionengine {
+
+/**
+ * Encapsulates all the interfaces and implementation details for performing
+ * display output composition.
+ */
+class CompositionEngine {
+public:
+ virtual ~CompositionEngine();
+};
+
+} // namespace compositionengine
+} // namespace android
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h
new file mode 100644
index 0000000..70519c1
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2018 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.
+ */
+
+#pragma once
+
+#include <memory>
+
+#include <compositionengine/CompositionEngine.h>
+
+namespace android::compositionengine::impl {
+
+class CompositionEngine : public compositionengine::CompositionEngine {
+public:
+ CompositionEngine();
+ ~CompositionEngine() override;
+};
+
+std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine();
+
+} // namespace android::compositionengine::impl
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/CompositionEngine.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/CompositionEngine.h
new file mode 100644
index 0000000..b1baf5e
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/CompositionEngine.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2018 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.
+ */
+
+#pragma once
+
+#include <compositionengine/CompositionEngine.h>
+#include <gmock/gmock.h>
+
+namespace android::compositionengine::mock {
+
+class CompositionEngine : public compositionengine::CompositionEngine {
+public:
+ CompositionEngine();
+ ~CompositionEngine() override;
+};
+
+} // namespace android::compositionengine::mock
diff --git a/services/surfaceflinger/CompositionEngine/mock/CompositionEngine.cpp b/services/surfaceflinger/CompositionEngine/mock/CompositionEngine.cpp
new file mode 100644
index 0000000..778a09e
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/mock/CompositionEngine.cpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2018 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 <compositionengine/mock/CompositionEngine.h>
+
+namespace android::compositionengine::mock {
+
+// The Google Mock documentation recommends explicit non-header instantiations
+// for better compile time performance.
+CompositionEngine::CompositionEngine() = default;
+CompositionEngine::~CompositionEngine() = default;
+
+} // namespace android::compositionengine::mock
diff --git a/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp b/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
new file mode 100644
index 0000000..b96de44
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2018 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 <memory>
+
+#include <compositionengine/impl/CompositionEngine.h>
+
+namespace android::compositionengine {
+
+CompositionEngine::~CompositionEngine() = default;
+
+namespace impl {
+
+std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() {
+ return std::make_unique<CompositionEngine>();
+}
+
+CompositionEngine::CompositionEngine() = default;
+CompositionEngine::~CompositionEngine() = default;
+
+} // namespace impl
+} // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp b/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp
new file mode 100644
index 0000000..0f3cc0b
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2018 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 <compositionengine/impl/CompositionEngine.h>
+#include <gtest/gtest.h>
+
+namespace android::compositionengine {
+namespace {
+
+class CompositionEngineTest : public testing::Test {
+public:
+ ~CompositionEngineTest() override;
+
+ impl::CompositionEngine engine;
+};
+
+CompositionEngineTest::~CompositionEngineTest() = default;
+
+TEST_F(CompositionEngineTest, canInstantiateCompositionEngine) {
+ auto engine = impl::createCompositionEngine();
+ EXPECT_TRUE(engine.get() != nullptr);
+}
+
+} // namespace
+} // namespace android::compositionengine
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 4a93be6..8345ce2 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -35,32 +35,29 @@
#include <binder/IServiceManager.h>
#include <binder/PermissionCache.h>
+#include <compositionengine/CompositionEngine.h>
#include <dvr/vr_flinger.h>
-
-#include <input/IInputFlinger.h>
-
-#include <ui/ColorSpace.h>
-#include <ui/DebugUtils.h>
-#include <ui/DisplayInfo.h>
-#include <ui/DisplayStatInfo.h>
-
#include <gui/BufferQueue.h>
#include <gui/GuiConfig.h>
#include <gui/IDisplayEventConnection.h>
#include <gui/IProducerListener.h>
#include <gui/LayerDebugInfo.h>
#include <gui/Surface.h>
+#include <input/IInputFlinger.h>
#include <renderengine/RenderEngine.h>
+#include <ui/ColorSpace.h>
+#include <ui/DebugUtils.h>
+#include <ui/DisplayInfo.h>
+#include <ui/DisplayStatInfo.h>
#include <ui/GraphicBufferAllocator.h>
#include <ui/PixelFormat.h>
#include <ui/UiConfig.h>
-
-#include <utils/misc.h>
-#include <utils/String8.h>
-#include <utils/String16.h>
#include <utils/StopWatch.h>
+#include <utils/String16.h>
+#include <utils/String8.h>
#include <utils/Timers.h>
#include <utils/Trace.h>
+#include <utils/misc.h>
#include <private/android_filesystem_config.h>
#include <private/gui/SyncFeatures.h>
@@ -272,7 +269,8 @@
mHasPoweredOff(false),
mNumLayers(0),
mVrFlingerRequestsDisplay(false),
- mMainThreadId(std::this_thread::get_id()) {}
+ mMainThreadId(std::this_thread::get_id()),
+ mCompositionEngine{getFactory().createCompositionEngine()} {}
SurfaceFlinger::SurfaceFlinger(surfaceflinger::Factory& factory)
: SurfaceFlinger(factory, SkipInitialization) {
@@ -544,6 +542,10 @@
return NO_ERROR;
}
+compositionengine::CompositionEngine& SurfaceFlinger::getCompositionEngine() const {
+ return *mCompositionEngine.get();
+}
+
void SurfaceFlinger::bootFinished()
{
if (mStartPropertySetThread->join() != NO_ERROR) {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index b1bfb3a..8e48572 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -336,6 +336,9 @@
surfaceflinger::Factory& getFactory() { return mFactory; }
+ // The CompositionEngine encapsulates all composition related interfaces and actions.
+ compositionengine::CompositionEngine& getCompositionEngine() const;
+
// returns the default Display
sp<const DisplayDevice> getDefaultDisplayDevice() const {
Mutex::Autolock _l(mStateLock);
@@ -991,6 +994,7 @@
ui::Dataspace mWideColorGamutCompositionDataspace;
SurfaceFlingerBE mBE;
+ std::unique_ptr<compositionengine::CompositionEngine> mCompositionEngine;
bool mUseScheduler = false;
std::unique_ptr<Scheduler> mScheduler;
diff --git a/services/surfaceflinger/SurfaceFlingerFactory.cpp b/services/surfaceflinger/SurfaceFlingerFactory.cpp
index 88649e3..f4a5dcd 100644
--- a/services/surfaceflinger/SurfaceFlingerFactory.cpp
+++ b/services/surfaceflinger/SurfaceFlingerFactory.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <compositionengine/impl/CompositionEngine.h>
#include <ui/GraphicBuffer.h>
#include "BufferQueueLayer.h"
@@ -102,6 +103,10 @@
return surfaceflinger::impl::createNativeWindowSurface(producer);
}
+ std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() override {
+ return compositionengine::impl::createCompositionEngine();
+ }
+
sp<ContainerLayer> createContainerLayer(const LayerCreationArgs& args) override {
return new ContainerLayer(args);
}
diff --git a/services/surfaceflinger/SurfaceFlingerFactory.h b/services/surfaceflinger/SurfaceFlingerFactory.h
index 1c27cc7..f747684 100644
--- a/services/surfaceflinger/SurfaceFlingerFactory.h
+++ b/services/surfaceflinger/SurfaceFlingerFactory.h
@@ -49,6 +49,9 @@
struct DisplayDeviceCreationArgs;
struct LayerCreationArgs;
+namespace compositionengine {
+class CompositionEngine;
+} // namespace compositionengine
namespace surfaceflinger {
class NativeWindowSurface;
@@ -78,6 +81,8 @@
virtual std::unique_ptr<surfaceflinger::NativeWindowSurface> createNativeWindowSurface(
const sp<IGraphicBufferProducer>&) = 0;
+ virtual std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() = 0;
+
virtual sp<BufferQueueLayer> createBufferQueueLayer(const LayerCreationArgs& args) = 0;
virtual sp<BufferStateLayer> createBufferStateLayer(const LayerCreationArgs& args) = 0;
virtual sp<ColorLayer> createColorLayer(const LayerCreationArgs& args) = 0;
diff --git a/services/surfaceflinger/TEST_MAPPING b/services/surfaceflinger/TEST_MAPPING
new file mode 100644
index 0000000..cab33ae
--- /dev/null
+++ b/services/surfaceflinger/TEST_MAPPING
@@ -0,0 +1,10 @@
+{
+ "presubmit": [
+ {
+ "name": "libsurfaceflinger_unittest"
+ },
+ {
+ "name": "libcompositionengine_test"
+ }
+ ]
+}
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index 2f35ae5..3fd355b 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -20,6 +20,16 @@
// Using the address sanitizer not only helps uncover issues in the code
// covered by the tests, but also covers some of the tricky injection of
// fakes the unit tests currently do.
+ //
+ // Note: If you get an runtime link error like:
+ //
+ // CANNOT LINK EXECUTABLE "/data/local/tmp/libsurfaceflinger_unittest": library "libclang_rt.asan-aarch64-android.so" not found
+ //
+ // it is because the address sanitizer shared objects are not installed
+ // by default in the system image.
+ //
+ // You can either "make dist tests" before flashing, or set this
+ // option to false temporarily.
address: true,
},
srcs: [
@@ -51,6 +61,8 @@
],
static_libs: [
"libgmock",
+ "libcompositionengine",
+ "libcompositionengine_mocks",
],
header_libs: [
"libsurfaceflinger_headers",
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 4da08b8..230dd99 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -16,6 +16,8 @@
#pragma once
+#include <compositionengine/impl/CompositionEngine.h>
+
#include "BufferQueueLayer.h"
#include "BufferStateLayer.h"
#include "ColorLayer.h"
@@ -113,6 +115,10 @@
return mCreateNativeWindowSurface(producer);
}
+ std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() override {
+ return compositionengine::impl::createCompositionEngine();
+ }
+
sp<BufferQueueLayer> createBufferQueueLayer(const LayerCreationArgs&) override {
// TODO: Use test-fixture controlled factory
return nullptr;
@@ -148,6 +154,10 @@
std::function<std::unique_ptr<surfaceflinger::NativeWindowSurface>(
const sp<IGraphicBufferProducer>&)>;
CreateNativeWindowSurfaceFunction mCreateNativeWindowSurface;
+
+ using CreateCompositionEngineFunction =
+ std::function<std::unique_ptr<compositionengine::CompositionEngine>()>;
+ CreateCompositionEngineFunction mCreateCompositionEngine;
};
} // namespace surfaceflinger::test