Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8cc5a154 authored by Chia-I Wu's avatar Chia-I Wu
Browse files

graphics: clean up composer VTS tests

Add libVtsHalGraphicsComposerUtils which provides a wrapper to
IComposer.  Port tests to be based on
libVtsHalGraphicsComposerUtils.

Test: manual
Change-Id: I400c347b54702c3d45954e6cdc101d3dc1241efd
parent 89d09ddb
Loading
Loading
Loading
Loading
+27 −1
Original line number Diff line number Diff line
@@ -14,6 +14,23 @@
// limitations under the License.
//

cc_library_static {
    name: "libVtsHalGraphicsComposerTestUtils",
    srcs: ["VtsHalGraphicsComposerTestUtils.cpp"],
    shared_libs: ["android.hardware.graphics.composer@2.1"],
    static_libs: [
        "VtsHalHidlTargetBaseTest",
    ],
    cflags: [
        "-Wall",
        "-Wextra",
        "-Werror",
        "-O0",
        "-g",
    ],
    export_include_dirs: ["."],
}

cc_test {
    name: "VtsHalGraphicsComposerV2_1TargetTest",
    srcs: ["VtsHalGraphicsComposerV2_1TargetTest.cpp"],
@@ -31,8 +48,17 @@ cc_test {
        "libsync",
        "libutils",
    ],
    static_libs: ["VtsHalHidlTargetBaseTest", "libhwcomposer-command-buffer"],
    static_libs: [
        "libhwcomposer-command-buffer",
        "libVtsHalGraphicsAllocatorTestUtils",
        "libVtsHalGraphicsComposerTestUtils",
        "libVtsHalGraphicsMapperTestUtils",
        "VtsHalHidlTargetBaseTest",
    ],
    cflags: [
        "-Wall",
        "-Wextra",
        "-Werror",
        "-O0",
        "-g",
    ]
+300 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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 <VtsHalHidlTargetBaseTest.h>

#include "VtsHalGraphicsComposerTestUtils.h"

namespace android {
namespace hardware {
namespace graphics {
namespace composer {
namespace V2_1 {
namespace tests {

Composer::Composer() { init(); }

void Composer::init() {
  mComposer = ::testing::VtsHalHidlTargetBaseTest::getService<IComposer>();
  ASSERT_NE(nullptr, mComposer.get()) << "failed to get composer service";

  std::vector<IComposer::Capability> capabilities = getCapabilities();
  mCapabilities.insert(capabilities.begin(), capabilities.end());
}

sp<IComposer> Composer::getRaw() const { return mComposer; }

bool Composer::hasCapability(IComposer::Capability capability) const {
  return mCapabilities.count(capability) > 0;
}

std::vector<IComposer::Capability> Composer::getCapabilities() {
  std::vector<IComposer::Capability> capabilities;
  mComposer->getCapabilities(
      [&](const auto& tmpCapabilities) { capabilities = tmpCapabilities; });

  return capabilities;
}

std::string Composer::dumpDebugInfo() {
  std::string debugInfo;
  mComposer->dumpDebugInfo(
      [&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });

  return debugInfo;
}

std::unique_ptr<ComposerClient> Composer::createClient() {
  std::unique_ptr<ComposerClient> client;
  mComposer->createClient([&](const auto& tmpError, const auto& tmpClient) {
    ASSERT_EQ(Error::NONE, tmpError) << "failed to create client";
    client = std::make_unique<ComposerClient>(tmpClient);
  });

  return client;
}

ComposerClient::ComposerClient(const sp<IComposerClient>& client)
    : mClient(client) {}

ComposerClient::~ComposerClient() {
  for (auto it : mDisplayResources) {
    Display display = it.first;
    DisplayResource& resource = it.second;

    for (auto layer : resource.layers) {
      EXPECT_EQ(Error::NONE, mClient->destroyLayer(display, layer))
          << "failed to destroy layer " << layer;
    }

    if (resource.isVirtual) {
      EXPECT_EQ(Error::NONE, mClient->destroyVirtualDisplay(display))
          << "failed to destroy virtual display " << display;
    }
  }
  mDisplayResources.clear();
}

sp<IComposerClient> ComposerClient::getRaw() const { return mClient; }

void ComposerClient::registerCallback(const sp<IComposerCallback>& callback) {
  mClient->registerCallback(callback);
}

uint32_t ComposerClient::getMaxVirtualDisplayCount() {
  return mClient->getMaxVirtualDisplayCount();
}

Display ComposerClient::createVirtualDisplay(uint32_t width, uint32_t height,
                                             PixelFormat formatHint,
                                             uint32_t outputBufferSlotCount,
                                             PixelFormat* outFormat) {
  Display display = 0;
  mClient->createVirtualDisplay(
      width, height, formatHint, outputBufferSlotCount,
      [&](const auto& tmpError, const auto& tmpDisplay, const auto& tmpFormat) {
        ASSERT_EQ(Error::NONE, tmpError) << "failed to create virtual display";
        display = tmpDisplay;
        *outFormat = tmpFormat;

        ASSERT_TRUE(
            mDisplayResources.insert({display, DisplayResource(true)}).second)
            << "duplicated virtual display id " << display;
      });

  return display;
}

void ComposerClient::destroyVirtualDisplay(Display display) {
  Error error = mClient->destroyVirtualDisplay(display);
  ASSERT_EQ(Error::NONE, error)
      << "failed to destroy virtual display " << display;

  mDisplayResources.erase(display);
}

Layer ComposerClient::createLayer(Display display, uint32_t bufferSlotCount) {
  Layer layer = 0;
  mClient->createLayer(
      display, bufferSlotCount,
      [&](const auto& tmpError, const auto& tmpLayer) {
        ASSERT_EQ(Error::NONE, tmpError) << "failed to create layer";
        layer = tmpLayer;

        auto resourceIt = mDisplayResources.find(display);
        if (resourceIt == mDisplayResources.end()) {
          resourceIt =
              mDisplayResources.insert({display, DisplayResource(false)}).first;
        }

        ASSERT_TRUE(resourceIt->second.layers.insert(layer).second)
            << "duplicated layer id " << layer;
      });

  return layer;
}

void ComposerClient::destroyLayer(Display display, Layer layer) {
  Error error = mClient->destroyLayer(display, layer);
  ASSERT_EQ(Error::NONE, error) << "failed to destroy layer " << layer;

  auto resourceIt = mDisplayResources.find(display);
  ASSERT_NE(mDisplayResources.end(), resourceIt);
  resourceIt->second.layers.erase(layer);
}

Config ComposerClient::getActiveConfig(Display display) {
  Config config = 0;
  mClient->getActiveConfig(
      display, [&](const auto& tmpError, const auto& tmpConfig) {
        ASSERT_EQ(Error::NONE, tmpError) << "failed to get active config";
        config = tmpConfig;
      });

  return config;
}

bool ComposerClient::getClientTargetSupport(Display display, uint32_t width,
                                            uint32_t height, PixelFormat format,
                                            Dataspace dataspace) {
  Error error = mClient->getClientTargetSupport(display, width, height, format,
                                                dataspace);
  return error == Error::NONE;
}

std::vector<ColorMode> ComposerClient::getColorModes(Display display) {
  std::vector<ColorMode> modes;
  mClient->getColorModes(
      display, [&](const auto& tmpError, const auto& tmpMode) {
        ASSERT_EQ(Error::NONE, tmpError) << "failed to get color mode";
        modes = tmpMode;
      });

  return modes;
}

int32_t ComposerClient::getDisplayAttribute(
    Display display, Config config, IComposerClient::Attribute attribute) {
  int32_t value = 0;
  mClient->getDisplayAttribute(display, config, attribute,
                               [&](const auto& tmpError, const auto& tmpValue) {
                                 ASSERT_EQ(Error::NONE, tmpError)
                                     << "failed to get display attribute";
                                 value = tmpValue;
                               });

  return value;
}

std::vector<Config> ComposerClient::getDisplayConfigs(Display display) {
  std::vector<Config> configs;
  mClient->getDisplayConfigs(
      display, [&](const auto& tmpError, const auto& tmpConfigs) {
        ASSERT_EQ(Error::NONE, tmpError) << "failed to get display configs";
        configs = tmpConfigs;
      });

  return configs;
}

std::string ComposerClient::getDisplayName(Display display) {
  std::string name;
  mClient->getDisplayName(
      display, [&](const auto& tmpError, const auto& tmpName) {
        ASSERT_EQ(Error::NONE, tmpError) << "failed to get display name";
        name = tmpName.c_str();
      });

  return name;
}

IComposerClient::DisplayType ComposerClient::getDisplayType(Display display) {
  IComposerClient::DisplayType type = IComposerClient::DisplayType::INVALID;
  mClient->getDisplayType(
      display, [&](const auto& tmpError, const auto& tmpType) {
        ASSERT_EQ(Error::NONE, tmpError) << "failed to get display type";
        type = tmpType;
      });

  return type;
}

bool ComposerClient::getDozeSupport(Display display) {
  bool support = false;
  mClient->getDozeSupport(
      display, [&](const auto& tmpError, const auto& tmpSupport) {
        ASSERT_EQ(Error::NONE, tmpError) << "failed to get doze support";
        support = tmpSupport;
      });

  return support;
}

std::vector<Hdr> ComposerClient::getHdrCapabilities(
    Display display, float* outMaxLuminance, float* outMaxAverageLuminance,
    float* outMinLuminance) {
  std::vector<Hdr> types;
  mClient->getHdrCapabilities(
      display,
      [&](const auto& tmpError, const auto& tmpTypes,
          const auto& tmpMaxLuminance, const auto& tmpMaxAverageLuminance,
          const auto& tmpMinLuminance) {
        ASSERT_EQ(Error::NONE, tmpError) << "failed to get HDR capabilities";
        types = tmpTypes;
        *outMaxLuminance = tmpMaxLuminance;
        *outMaxAverageLuminance = tmpMaxAverageLuminance;
        *outMinLuminance = tmpMinLuminance;
      });

  return types;
}

void ComposerClient::setClientTargetSlotCount(Display display,
                                              uint32_t clientTargetSlotCount) {
  Error error =
      mClient->setClientTargetSlotCount(display, clientTargetSlotCount);
  ASSERT_EQ(Error::NONE, error) << "failed to set client target slot count";
}

void ComposerClient::setActiveConfig(Display display, Config config) {
  Error error = mClient->setActiveConfig(display, config);
  ASSERT_EQ(Error::NONE, error) << "failed to set active config";
}

void ComposerClient::setColorMode(Display display, ColorMode mode) {
  Error error = mClient->setColorMode(display, mode);
  ASSERT_EQ(Error::NONE, error) << "failed to set color mode";
}

void ComposerClient::setPowerMode(Display display,
                                  IComposerClient::PowerMode mode) {
  Error error = mClient->setPowerMode(display, mode);
  ASSERT_EQ(Error::NONE, error) << "failed to set power mode";
}

void ComposerClient::setVsyncEnabled(Display display, bool enabled) {
  IComposerClient::Vsync vsync = (enabled) ? IComposerClient::Vsync::ENABLE
                                           : IComposerClient::Vsync::DISABLE;
  Error error = mClient->setVsyncEnabled(display, vsync);
  ASSERT_EQ(Error::NONE, error) << "failed to set vsync mode";
}

}  // namespace tests
}  // namespace V2_1
}  // namespace composer
}  // namespace graphics
}  // namespace hardware
}  // namespace android
+126 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.
 */

#ifndef VTS_HAL_GRAPHICS_COMPOSER_UTILS
#define VTS_HAL_GRAPHICS_COMPOSER_UTILS

#include <memory>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <android/hardware/graphics/composer/2.1/IComposer.h>
#include <utils/StrongPointer.h>

namespace android {
namespace hardware {
namespace graphics {
namespace composer {
namespace V2_1 {
namespace tests {

using android::hardware::graphics::common::V1_0::ColorMode;
using android::hardware::graphics::common::V1_0::Dataspace;
using android::hardware::graphics::common::V1_0::Hdr;
using android::hardware::graphics::common::V1_0::PixelFormat;

class ComposerClient;

// A wrapper to IComposer.
class Composer {
 public:
  Composer();

  sp<IComposer> getRaw() const;

  // Returns true when the composer supports the specified capability.
  bool hasCapability(IComposer::Capability capability) const;

  std::vector<IComposer::Capability> getCapabilities();
  std::string dumpDebugInfo();
  std::unique_ptr<ComposerClient> createClient();

 private:
  void init();

  sp<IComposer> mComposer;
  std::unordered_set<IComposer::Capability> mCapabilities;
};

// A wrapper to IComposerClient.
class ComposerClient {
 public:
  ComposerClient(const sp<IComposerClient>& client);
  ~ComposerClient();

  sp<IComposerClient> getRaw() const;

  void registerCallback(const sp<IComposerCallback>& callback);
  uint32_t getMaxVirtualDisplayCount();

  Display createVirtualDisplay(uint32_t width, uint32_t height,
                               PixelFormat formatHint,
                               uint32_t outputBufferSlotCount,
                               PixelFormat* outFormat);
  void destroyVirtualDisplay(Display display);

  Layer createLayer(Display display, uint32_t bufferSlotCount);
  void destroyLayer(Display display, Layer layer);

  Config getActiveConfig(Display display);
  bool getClientTargetSupport(Display display, uint32_t width, uint32_t height,
                              PixelFormat format, Dataspace dataspace);
  std::vector<ColorMode> getColorModes(Display display);
  int32_t getDisplayAttribute(Display display, Config config,
                              IComposerClient::Attribute attribute);
  std::vector<Config> getDisplayConfigs(Display display);
  std::string getDisplayName(Display display);
  IComposerClient::DisplayType getDisplayType(Display display);
  bool getDozeSupport(Display display);
  std::vector<Hdr> getHdrCapabilities(Display display, float* outMaxLuminance,
                                      float* outMaxAverageLuminance,
                                      float* outMinLuminance);

  void setClientTargetSlotCount(Display display,
                                uint32_t clientTargetSlotCount);
  void setActiveConfig(Display display, Config config);
  void setColorMode(Display display, ColorMode mode);
  void setPowerMode(Display display, IComposerClient::PowerMode mode);
  void setVsyncEnabled(Display display, bool enabled);

 private:
  sp<IComposerClient> mClient;

  // Keep track of all virtual displays and layers.  When a test fails with
  // ASSERT_*, the destructor will clean up the resources for the test.
  struct DisplayResource {
    DisplayResource(bool isVirtual_) : isVirtual(isVirtual_) {}

    bool isVirtual;
    std::unordered_set<Layer> layers;
  };
  std::unordered_map<Display, DisplayResource> mDisplayResources;
};

}  // namespace tests
}  // namespace V2_1
}  // namespace composer
}  // namespace graphics
}  // namespace hardware
}  // namespace android

#endif  // VTS_HAL_GRAPHICS_COMPOSER_UTILS
+123 −409

File changed.

Preview size limit exceeded, changes collapsed.