1/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "graphics_composer_hidl_hal_test@2.2"
18
19#include <VtsHalHidlTargetTestBase.h>
20#include <android-base/logging.h>
21#include <android/hardware/graphics/mapper/2.1/IMapper.h>
22#include <composer-vts/2.1/GraphicsComposerCallback.h>
23#include <composer-vts/2.1/TestCommandReader.h>
24#include <composer-vts/2.2/ComposerVts.h>
25#include <mapper-vts/2.1/MapperVts.h>
26
27namespace android {
28namespace hardware {
29namespace graphics {
30namespace composer {
31namespace V2_2 {
32namespace vts {
33namespace {
34
35using android::hardware::graphics::common::V1_0::BufferUsage;
36using android::hardware::graphics::common::V1_0::ColorTransform;
37using android::hardware::graphics::common::V1_0::Transform;
38using android::hardware::graphics::common::V1_1::ColorMode;
39using android::hardware::graphics::common::V1_1::Dataspace;
40using android::hardware::graphics::common::V1_1::PixelFormat;
41using android::hardware::graphics::common::V1_1::RenderIntent;
42using android::hardware::graphics::composer::V2_2::IComposerClient;
43using android::hardware::graphics::mapper::V2_1::IMapper;
44using android::hardware::graphics::mapper::V2_1::vts::Gralloc;
45using GrallocError = android::hardware::graphics::mapper::V2_0::Error;
46
47// Test environment for graphics.composer
48class GraphicsComposerHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
49   public:
50    // get the test environment singleton
51    static GraphicsComposerHidlEnvironment* Instance() {
52        static GraphicsComposerHidlEnvironment* instance = new GraphicsComposerHidlEnvironment;
53        return instance;
54    }
55
56    virtual void registerTestServices() override { registerTestService<IComposer>(); }
57
58   private:
59    GraphicsComposerHidlEnvironment() {}
60
61    GTEST_DISALLOW_COPY_AND_ASSIGN_(GraphicsComposerHidlEnvironment);
62};
63
64class GraphicsComposerHidlTest : public ::testing::VtsHalHidlTargetTestBase {
65   protected:
66    void SetUp() override {
67        ASSERT_NO_FATAL_FAILURE(
68            mComposer = std::make_unique<Composer_v2_2>(
69                GraphicsComposerHidlEnvironment::Instance()->getServiceName<IComposer>()));
70        ASSERT_NO_FATAL_FAILURE(mComposerClient = mComposer->createClient_v2_2());
71
72        mComposerCallback = new V2_1::vts::GraphicsComposerCallback;
73        mComposerClient->registerCallback(mComposerCallback);
74
75        // assume the first display is primary and is never removed
76        mPrimaryDisplay = waitForFirstDisplay();
77
78        // explicitly disable vsync
79        mComposerClient->setVsyncEnabled(mPrimaryDisplay, false);
80        mComposerCallback->setVsyncAllowed(false);
81
82        mComposerClient->getRaw()->getReadbackBufferAttributes(
83            mPrimaryDisplay, [&](const auto& tmpError, const auto&, const auto&) {
84                mHasReadbackBuffer = tmpError == Error::NONE;
85            });
86    }
87
88    void TearDown() override {
89        if (mComposerCallback != nullptr) {
90            EXPECT_EQ(0, mComposerCallback->getInvalidHotplugCount());
91            EXPECT_EQ(0, mComposerCallback->getInvalidRefreshCount());
92            EXPECT_EQ(0, mComposerCallback->getInvalidVsyncCount());
93        }
94    }
95
96    // use the slot count usually set by SF
97    static constexpr uint32_t kBufferSlotCount = 64;
98
99    std::unique_ptr<Composer_v2_2> mComposer;
100    std::unique_ptr<ComposerClient_v2_2> mComposerClient;
101    sp<V2_1::vts::GraphicsComposerCallback> mComposerCallback;
102    // the first display and is assumed never to be removed
103    Display mPrimaryDisplay;
104    bool mHasReadbackBuffer;
105
106   private:
107    Display waitForFirstDisplay() {
108        while (true) {
109            std::vector<Display> displays = mComposerCallback->getDisplays();
110            if (displays.empty()) {
111                usleep(5 * 1000);
112                continue;
113            }
114
115            return displays[0];
116        }
117    }
118};
119
120// Tests for IComposerClient::Command.
121class GraphicsComposerHidlCommandTest : public GraphicsComposerHidlTest {
122   protected:
123    void SetUp() override {
124        ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::SetUp());
125
126        ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>());
127
128        mWriter = std::make_unique<V2_2::CommandWriterBase>(1024);
129        mReader = std::make_unique<V2_1::vts::TestCommandReader>();
130    }
131
132    void TearDown() override { ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::TearDown()); }
133
134    const native_handle_t* allocate() {
135        IMapper::BufferDescriptorInfo info{};
136        info.width = 64;
137        info.height = 64;
138        info.layerCount = 1;
139        info.format = PixelFormat::RGBA_8888;
140        info.usage =
141            static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN);
142
143        return mGralloc->allocate(info);
144    }
145
146    void execute() { mComposerClient->execute_v2_2(mReader.get(), mWriter.get()); }
147
148    std::unique_ptr<V2_2::CommandWriterBase> mWriter;
149    std::unique_ptr<V2_1::vts::TestCommandReader> mReader;
150
151   private:
152    std::unique_ptr<Gralloc> mGralloc;
153};
154
155/**
156 * Test IComposerClient::Command::SET_LAYER_PER_FRAME_METADATA.
157 */
158TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_PER_FRAME_METADATA) {
159    Layer layer;
160    ASSERT_NO_FATAL_FAILURE(layer =
161                                mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
162
163    mWriter->selectDisplay(mPrimaryDisplay);
164    mWriter->selectLayer(layer);
165
166    /**
167     * DISPLAY_P3 is a color space that uses the DCI_P3 primaries,
168     * the D65 white point and the SRGB transfer functions.
169     * Rendering Intent: Colorimetric
170     * Primaries:
171     *                  x       y
172     *  green           0.265   0.690
173     *  blue            0.150   0.060
174     *  red             0.680   0.320
175     *  white (D65)     0.3127  0.3290
176     */
177
178    std::vector<IComposerClient::PerFrameMetadata> hidlMetadata;
179    hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X, 0.680});
180    hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y, 0.320});
181    hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X, 0.265});
182    hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y, 0.690});
183    hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X, 0.150});
184    hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y, 0.060});
185    hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::WHITE_POINT_X, 0.3127});
186    hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::WHITE_POINT_Y, 0.3290});
187    hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::MAX_LUMINANCE, 100.0});
188    hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::MIN_LUMINANCE, 0.1});
189    hidlMetadata.push_back({IComposerClient::PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL, 78.0});
190    hidlMetadata.push_back(
191        {IComposerClient::PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL, 62.0});
192    mWriter->setLayerPerFrameMetadata(hidlMetadata);
193    execute();
194}
195
196/**
197 * Test IComposerClient::getPerFrameMetadataKeys.
198 */
199TEST_F(GraphicsComposerHidlTest, GetPerFrameMetadataKeys) {
200    mComposerClient->getPerFrameMetadataKeys(mPrimaryDisplay);
201}
202
203/**
204 * Test IComposerClient::createVirtualDisplay_2_2 and
205 * IComposerClient::destroyVirtualDisplay.
206 *
207 * Test that virtual displays can be created and has the correct display type.
208 */
209TEST_F(GraphicsComposerHidlTest, CreateVirtualDisplay_2_2) {
210    if (mComposerClient->getMaxVirtualDisplayCount() == 0) {
211        GTEST_SUCCEED() << "no virtual display support";
212        return;
213    }
214
215    Display display;
216    PixelFormat format;
217    ASSERT_NO_FATAL_FAILURE(
218        display = mComposerClient->createVirtualDisplay_2_2(
219            64, 64, PixelFormat::IMPLEMENTATION_DEFINED, kBufferSlotCount, &format));
220
221    // test display type
222    IComposerClient::DisplayType type = mComposerClient->getDisplayType(display);
223    EXPECT_EQ(IComposerClient::DisplayType::VIRTUAL, type);
224
225    mComposerClient->destroyVirtualDisplay(display);
226}
227
228/**
229 * Test IComposerClient::getClientTargetSupport_2_2.
230 *
231 * Test that IComposerClient::getClientTargetSupport returns true for the
232 * required client targets.
233 */
234TEST_F(GraphicsComposerHidlTest, GetClientTargetSupport_2_2) {
235    std::vector<Config> configs = mComposerClient->getDisplayConfigs(mPrimaryDisplay);
236    for (auto config : configs) {
237        int32_t width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
238                                                             IComposerClient::Attribute::WIDTH);
239        int32_t height = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
240                                                              IComposerClient::Attribute::HEIGHT);
241        ASSERT_LT(0, width);
242        ASSERT_LT(0, height);
243
244        mComposerClient->setActiveConfig(mPrimaryDisplay, config);
245
246        ASSERT_TRUE(mComposerClient->getClientTargetSupport_2_2(
247            mPrimaryDisplay, width, height, PixelFormat::RGBA_8888, Dataspace::UNKNOWN));
248    }
249}
250
251/**
252 * Test IComposerClient::setPowerMode_2_2.
253 */
254TEST_F(GraphicsComposerHidlTest, setPowerMode_2_2) {
255    std::vector<IComposerClient::PowerMode> modes;
256    modes.push_back(IComposerClient::PowerMode::OFF);
257    modes.push_back(IComposerClient::PowerMode::ON_SUSPEND);
258    modes.push_back(IComposerClient::PowerMode::ON);
259
260    for (auto mode : modes) {
261        mComposerClient->setPowerMode_2_2(mPrimaryDisplay, mode);
262    }
263}
264
265TEST_F(GraphicsComposerHidlTest, setReadbackBuffer) {
266    if (!mHasReadbackBuffer) {
267        return;
268    }
269
270    PixelFormat pixelFormat;
271    Dataspace dataspace;
272    mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay, &pixelFormat, &dataspace);
273    ASSERT_LT(static_cast<PixelFormat>(0), pixelFormat);
274    ASSERT_NE(Dataspace::UNKNOWN, dataspace);
275
276    IMapper::BufferDescriptorInfo info{};
277    Config config = mComposerClient->getActiveConfig(mPrimaryDisplay);
278    info.width = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
279                                                      IComposerClient::Attribute::WIDTH);
280    info.height = mComposerClient->getDisplayAttribute(mPrimaryDisplay, config,
281                                                       IComposerClient::Attribute::HEIGHT);
282    info.layerCount = 1;
283    info.format = pixelFormat;
284    // BufferUsage::COMPOSER_OUTPUT is missing
285    info.usage = static_cast<uint64_t>(BufferUsage::COMPOSER_OVERLAY | BufferUsage::CPU_READ_OFTEN);
286
287    std::unique_ptr<Gralloc> gralloc;
288    const native_handle_t* buffer;
289    ASSERT_NO_FATAL_FAILURE(gralloc = std::make_unique<Gralloc>());
290    ASSERT_NO_FATAL_FAILURE(buffer = gralloc->allocate(info));
291
292    mComposerClient->setReadbackBuffer(mPrimaryDisplay, buffer, -1);
293}
294
295TEST_F(GraphicsComposerHidlTest, getReadbackBufferFenceInactive) {
296    if (!mHasReadbackBuffer) {
297        return;
298    }
299
300    mComposerClient->getRaw()->getReadbackBufferFence(
301        mPrimaryDisplay, [&](const auto& tmpError, const auto&) {
302            ASSERT_EQ(Error::UNSUPPORTED, tmpError) << "readback buffer is active";
303        });
304}
305
306/**
307 * Test IComposerClient::Command::SET_LAYER_FLOAT_COLOR.
308 */
309TEST_F(GraphicsComposerHidlCommandTest, SET_LAYER_FLOAT_COLOR) {
310    V2_1::Layer layer;
311    ASSERT_NO_FATAL_FAILURE(layer =
312                                mComposerClient->createLayer(mPrimaryDisplay, kBufferSlotCount));
313
314    mWriter->selectDisplay(mPrimaryDisplay);
315    mWriter->selectLayer(layer);
316    mWriter->setLayerFloatColor(IComposerClient::FloatColor{1.0, 1.0, 1.0, 1.0});
317    mWriter->setLayerFloatColor(IComposerClient::FloatColor{0.0, 0.0, 0.0, 0.0});
318}
319
320/**
321 * Test IComposerClient::getDataspaceSaturationMatrix.
322 */
323TEST_F(GraphicsComposerHidlTest, getDataspaceSaturationMatrix) {
324    auto matrix = mComposerClient->getDataspaceSaturationMatrix(Dataspace::SRGB_LINEAR);
325    // the last row is known
326    ASSERT_EQ(0.0f, matrix[12]);
327    ASSERT_EQ(0.0f, matrix[13]);
328    ASSERT_EQ(0.0f, matrix[14]);
329    ASSERT_EQ(1.0f, matrix[15]);
330}
331
332/**
333 * Test IComposerClient::getColorMode_2_2.
334 */
335TEST_F(GraphicsComposerHidlTest, GetColorMode_2_2) {
336    std::vector<ColorMode> modes = mComposerClient->getColorModes(mPrimaryDisplay);
337
338    auto nativeMode = std::find(modes.cbegin(), modes.cend(), ColorMode::NATIVE);
339    EXPECT_NE(modes.cend(), nativeMode);
340}
341
342/**
343 * Test IComposerClient::getRenderIntent.
344 */
345TEST_F(GraphicsComposerHidlTest, GetRenderIntent) {
346    std::vector<ColorMode> modes = mComposerClient->getColorModes(mPrimaryDisplay);
347    for (auto mode : modes) {
348        std::vector<RenderIntent> intents =
349            mComposerClient->getRenderIntents(mPrimaryDisplay, mode);
350
351        bool isHdr;
352        switch (mode) {
353            case ColorMode::BT2100_PQ:
354            case ColorMode::BT2100_HLG:
355                isHdr = true;
356                break;
357            default:
358                isHdr = false;
359                break;
360        }
361        RenderIntent requiredIntent =
362            isHdr ? RenderIntent::TONE_MAP_COLORIMETRIC : RenderIntent::COLORIMETRIC;
363
364        auto iter = std::find(intents.cbegin(), intents.cend(), requiredIntent);
365        EXPECT_NE(intents.cend(), iter);
366    }
367}
368
369/**
370 * Test IComposerClient::setColorMode_2_2.
371 */
372TEST_F(GraphicsComposerHidlTest, SetColorMode_2_2) {
373    std::vector<ColorMode> modes = mComposerClient->getColorModes(mPrimaryDisplay);
374    for (auto mode : modes) {
375        std::vector<RenderIntent> intents =
376            mComposerClient->getRenderIntents(mPrimaryDisplay, mode);
377        for (auto intent : intents) {
378            mComposerClient->setColorMode(mPrimaryDisplay, mode, intent);
379        }
380    }
381}
382
383}  // namespace
384}  // namespace vts
385}  // namespace V2_2
386}  // namespace composer
387}  // namespace graphics
388}  // namespace hardware
389}  // namespace android
390
391int main(int argc, char** argv) {
392    using android::hardware::graphics::composer::V2_2::vts::GraphicsComposerHidlEnvironment;
393    ::testing::AddGlobalTestEnvironment(GraphicsComposerHidlEnvironment::Instance());
394    ::testing::InitGoogleTest(&argc, argv);
395    GraphicsComposerHidlEnvironment::Instance()->init(&argc, argv);
396    int status = RUN_ALL_TESTS();
397    return status;
398}
399