diff options
| author | 2018-01-17 11:57:07 -0800 | |
|---|---|---|
| committer | 2018-02-16 14:37:30 -0800 | |
| commit | 5b36f3f1330b15a60c9f6d114c5ecdb8b6e1234a (patch) | |
| tree | e6b3ab104459a8fe8c77b42d2063f7ddd6ee19d7 | |
| parent | 12eb423785adba54be4c7112e5198a80d563896e (diff) | |
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
7 files changed, 217 insertions, 1 deletions
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp index 3eb07aec2e..353b24546d 100644 --- a/services/surfaceflinger/tests/unittests/Android.bp +++ b/services/surfaceflinger/tests/unittests/Android.bp @@ -22,6 +22,8 @@ cc_test { "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 3841209aa1..fafc54ee65 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 @@ protected: 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 @@ protected: // 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 @@ DisplayTransactionTest::DisplayTransactionTest() { ::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 @@ void DisplayTransactionTest::setupPrimaryDisplay(int width, int height) { 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 @@ TEST_F(DisplayTransactionTest, processDisplayChangesLockedProcessesPrimaryDispla 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 @@ TEST_F(DisplayTransactionTest, processDisplayChangesLockedProcessesPrimaryDispla 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 0000000000..4b27e75129 --- /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 0000000000..98f24c2d44 --- /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 0000000000..e6f0c631e1 --- /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 0000000000..c98f39f43c --- /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 e55d778952..4895e16d31 100644 --- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h @@ -50,6 +50,12 @@ public: HWC2::Connection::Connected); } + using CreateBufferQueueFunction = SurfaceFlinger::CreateBufferQueueFunction; + + void setCreateBufferQueueFunction(CreateBufferQueueFunction f) { + mFlinger->mCreateBufferQueue = f; + } + /* ------------------------------------------------------------------------ * Forwarding for functions being tested */ |