SF: Add and use MockGraphicBufferProducer/Consumer
This has the benefit of allowing the tests to set expectations on the
producer/consumer queue calls.
Additionally this speeds up test execution (though possibly only for the
first test which creates a buffer queue) by a factor of 4x.
[Test execution time reduced from 25ms to 6.1ms]
Test: libsurfaceflinger_unittest passes on Pixel XL
Bug: None
Change-Id: Ic400e8d123fea497061c193df5036218ebef1d3a
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index 3eb07ae..353b245 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -22,6 +22,8 @@
"DisplayTransactionTest.cpp",
"MockComposer.cpp",
"MockEventThread.cpp",
+ "MockGraphicBufferConsumer.cpp",
+ "MockGraphicBufferProducer.cpp",
"MockRenderEngine.cpp",
],
static_libs: [
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index 3841209..fafc54e 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -24,6 +24,8 @@
#include "MockComposer.h"
#include "MockEventThread.h"
+#include "MockGraphicBufferConsumer.h"
+#include "MockGraphicBufferProducer.h"
#include "MockRenderEngine.h"
#include "TestableSurfaceFlinger.h"
@@ -53,6 +55,8 @@
void setupComposer(int virtualDisplayCount);
void setupPrimaryDisplay(int width, int height);
+ void expectFramebufferQueuePairCreation(int width, int height);
+
TestableSurfaceFlinger mFlinger;
mock::EventThread* mEventThread = new mock::EventThread();
@@ -61,6 +65,10 @@
// to keep a reference to them for use in setting up call expectations.
RE::mock::RenderEngine* mRenderEngine = new RE::mock::RenderEngine();
Hwc2::mock::Composer* mComposer = new Hwc2::mock::Composer();
+
+ // These mocks are created only when expected to be created via a factory.
+ sp<mock::GraphicBufferConsumer> mConsumer;
+ sp<mock::GraphicBufferProducer> mProducer;
};
DisplayTransactionTest::DisplayTransactionTest() {
@@ -68,6 +76,10 @@
::testing::UnitTest::GetInstance()->current_test_info();
ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
+ mFlinger.setCreateBufferQueueFunction([](auto, auto, auto) {
+ ADD_FAILURE() << "Unexpected request to create a buffer queue.";
+ });
+
mFlinger.mutableEventThread().reset(mEventThread);
mFlinger.setupRenderEngine(std::unique_ptr<RE::RenderEngine>(mRenderEngine));
@@ -122,6 +134,27 @@
Mock::VerifyAndClear(mComposer);
}
+void DisplayTransactionTest::expectFramebufferQueuePairCreation(int width, int height) {
+ mConsumer = new mock::GraphicBufferConsumer();
+ mProducer = new mock::GraphicBufferProducer();
+
+ mFlinger.setCreateBufferQueueFunction([this](auto outProducer, auto outConsumer, bool) {
+ *outProducer = mProducer;
+ *outConsumer = mConsumer;
+ });
+
+ EXPECT_CALL(*mConsumer, consumerConnect(_, false)).WillOnce(Return(NO_ERROR));
+ EXPECT_CALL(*mConsumer, setConsumerName(_)).WillRepeatedly(Return(NO_ERROR));
+ EXPECT_CALL(*mConsumer,
+ setConsumerUsageBits(GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER |
+ GRALLOC_USAGE_HW_FB))
+ .WillRepeatedly(Return(NO_ERROR));
+ EXPECT_CALL(*mConsumer, setDefaultBufferSize(width, height)).WillRepeatedly(Return(NO_ERROR));
+ EXPECT_CALL(*mConsumer, setMaxAcquiredBufferCount(_)).WillRepeatedly(Return(NO_ERROR));
+
+ EXPECT_CALL(*mProducer, allocateBuffers(0, 0, 0, 0)).WillRepeatedly(Return());
+}
+
TEST_F(DisplayTransactionTest, processDisplayChangesLockedProcessesPrimaryDisplayConnected) {
using android::hardware::graphics::common::V1_0::ColorMode;
@@ -135,10 +168,11 @@
EXPECT_CALL(*mComposer, getColorModes(DisplayDevice::DISPLAY_PRIMARY, _))
.WillOnce(DoAll(SetArgPointee<1>(std::vector<ColorMode>({ColorMode::NATIVE})),
Return(Error::NONE)));
-
EXPECT_CALL(*mComposer, getHdrCapabilities(DisplayDevice::DISPLAY_PRIMARY, _, _, _, _))
.WillOnce(DoAll(SetArgPointee<1>(std::vector<Hdr>()), Return(Error::NONE)));
+ expectFramebufferQueuePairCreation(1920, 1080);
+
auto reSurface = new RE::mock::Surface();
EXPECT_CALL(*mRenderEngine, createSurface())
.WillOnce(Return(ByMove(std::unique_ptr<RE::Surface>(reSurface))));
@@ -166,6 +200,8 @@
EXPECT_CALL(*mComposer, setVsyncEnabled(0, IComposerClient::Vsync::DISABLE))
.WillOnce(Return(Error::NONE));
+
+ EXPECT_CALL(*mConsumer, consumerDisconnect()).Times(1);
}
} // namespace
diff --git a/services/surfaceflinger/tests/unittests/MockGraphicBufferConsumer.cpp b/services/surfaceflinger/tests/unittests/MockGraphicBufferConsumer.cpp
new file mode 100644
index 0000000..4b27e75
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/MockGraphicBufferConsumer.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 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 "MockGraphicBufferConsumer.h"
+
+namespace android {
+namespace mock {
+
+// Explicit default instantiation is recommended.
+GraphicBufferConsumer::GraphicBufferConsumer() = default;
+GraphicBufferConsumer::~GraphicBufferConsumer() = default;
+
+} // namespace mock
+} // namespace android
\ No newline at end of file
diff --git a/services/surfaceflinger/tests/unittests/MockGraphicBufferConsumer.h b/services/surfaceflinger/tests/unittests/MockGraphicBufferConsumer.h
new file mode 100644
index 0000000..98f24c2
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/MockGraphicBufferConsumer.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 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 <gmock/gmock.h>
+
+#include <gui/IGraphicBufferConsumer.h>
+
+#include <utils/RefBase.h>
+
+namespace android {
+namespace mock {
+
+class GraphicBufferConsumer : public BnGraphicBufferConsumer, public virtual android::RefBase {
+public:
+ GraphicBufferConsumer();
+ ~GraphicBufferConsumer() override;
+
+ MOCK_METHOD3(acquireBuffer, status_t(BufferItem*, nsecs_t, uint64_t));
+ MOCK_METHOD1(detachBuffer, status_t(int));
+ MOCK_METHOD2(attachBuffer, status_t(int*, const sp<GraphicBuffer>&));
+ MOCK_METHOD5(releaseBuffer, status_t(int, uint64_t, EGLDisplay, EGLSyncKHR, const sp<Fence>&));
+ MOCK_METHOD2(consumerConnect, status_t(const sp<IConsumerListener>&, bool));
+ MOCK_METHOD0(consumerDisconnect, status_t());
+ MOCK_METHOD1(getReleasedBuffers, status_t(uint64_t*));
+ MOCK_METHOD2(setDefaultBufferSize, status_t(uint32_t, uint32_t));
+ MOCK_METHOD1(setMaxBufferCount, status_t(int));
+ MOCK_METHOD1(setMaxAcquiredBufferCount, status_t(int));
+ MOCK_METHOD1(setConsumerName, status_t(const String8&));
+ MOCK_METHOD1(setDefaultBufferFormat, status_t(PixelFormat));
+ MOCK_METHOD1(setDefaultBufferDataSpace, status_t(android_dataspace));
+ MOCK_METHOD1(setConsumerUsageBits, status_t(uint64_t));
+ MOCK_METHOD1(setConsumerIsProtected, status_t(bool));
+ MOCK_METHOD1(setTransformHint, status_t(uint32_t));
+ MOCK_CONST_METHOD1(getSidebandStream, status_t(sp<NativeHandle>*));
+ MOCK_METHOD2(getOccupancyHistory, status_t(bool, std::vector<OccupancyTracker::Segment>*));
+ MOCK_METHOD0(discardFreeBuffers, status_t());
+ MOCK_CONST_METHOD2(dumpState, status_t(const String8&, String8*));
+};
+
+} // namespace mock
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/MockGraphicBufferProducer.cpp b/services/surfaceflinger/tests/unittests/MockGraphicBufferProducer.cpp
new file mode 100644
index 0000000..e6f0c63
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/MockGraphicBufferProducer.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 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 "MockGraphicBufferProducer.h"
+
+namespace android {
+namespace mock {
+
+// Explicit default instantiation is recommended.
+GraphicBufferProducer::GraphicBufferProducer() = default;
+GraphicBufferProducer::~GraphicBufferProducer() = default;
+
+} // namespace mock
+} // namespace android
\ No newline at end of file
diff --git a/services/surfaceflinger/tests/unittests/MockGraphicBufferProducer.h b/services/surfaceflinger/tests/unittests/MockGraphicBufferProducer.h
new file mode 100644
index 0000000..c98f39f
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/MockGraphicBufferProducer.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 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 <gmock/gmock.h>
+
+#include <gui/IGraphicBufferProducer.h>
+
+#include <utils/RefBase.h>
+
+namespace android {
+namespace mock {
+
+class GraphicBufferProducer : public BnGraphicBufferProducer, public virtual android::RefBase {
+public:
+ GraphicBufferProducer();
+ ~GraphicBufferProducer() override;
+
+ MOCK_METHOD2(requestBuffer, status_t(int, sp<GraphicBuffer>*));
+ MOCK_METHOD1(setMaxDequeuedBufferCount, status_t(int));
+ MOCK_METHOD1(setAsyncMode, status_t(bool));
+ MOCK_METHOD8(dequeueBuffer,
+ status_t(int*, sp<Fence>*, uint32_t, uint32_t, PixelFormat, uint64_t, uint64_t*,
+ FrameEventHistoryDelta*));
+ MOCK_METHOD1(detachBuffer, status_t(int));
+ MOCK_METHOD2(detachNextBuffer, status_t(sp<GraphicBuffer>*, sp<Fence>*));
+ MOCK_METHOD2(attachBuffer, status_t(int*, const sp<GraphicBuffer>&));
+ MOCK_METHOD3(queueBuffer, status_t(int, const QueueBufferInput&, QueueBufferOutput*));
+ MOCK_METHOD2(cancelBuffer, status_t(int, const sp<Fence>&));
+ MOCK_METHOD2(query, int(int, int*));
+ MOCK_METHOD4(connect, status_t(const sp<IProducerListener>&, int, bool, QueueBufferOutput*));
+ MOCK_METHOD2(disconnect, status_t(int, DisconnectMode));
+ MOCK_METHOD1(setSidebandStream, status_t(const sp<NativeHandle>&));
+ MOCK_METHOD4(allocateBuffers, void(uint32_t, uint32_t, PixelFormat, uint64_t));
+ MOCK_METHOD1(allowAllocation, status_t(bool));
+ MOCK_METHOD1(setGenerationNumber, status_t(uint32_t));
+ MOCK_CONST_METHOD0(getConsumerName, String8());
+ MOCK_METHOD1(setSharedBufferMode, status_t(bool));
+ MOCK_METHOD1(setAutoRefresh, status_t(bool));
+ MOCK_METHOD1(setDequeueTimeout, status_t(nsecs_t));
+ MOCK_METHOD3(getLastQueuedBuffer, status_t(sp<GraphicBuffer>*, sp<Fence>*, float[16]));
+ MOCK_METHOD1(getFrameTimestamps, void(FrameEventHistoryDelta*));
+ MOCK_CONST_METHOD1(getUniqueId, status_t(uint64_t*));
+ MOCK_CONST_METHOD1(getConsumerUsage, status_t(uint64_t*));
+};
+
+} // namespace mock
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index e55d778..4895e16 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -50,6 +50,12 @@
HWC2::Connection::Connected);
}
+ using CreateBufferQueueFunction = SurfaceFlinger::CreateBufferQueueFunction;
+
+ void setCreateBufferQueueFunction(CreateBufferQueueFunction f) {
+ mFlinger->mCreateBufferQueue = f;
+ }
+
/* ------------------------------------------------------------------------
* Forwarding for functions being tested
*/