/** * Copyright (c) 2022, 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "GraphicsComposerCallback.h" using aidl::android::hardware::graphics::common::Dataspace; using aidl::android::hardware::graphics::common::DisplayDecorationSupport; using aidl::android::hardware::graphics::common::FRect; using aidl::android::hardware::graphics::common::PixelFormat; using aidl::android::hardware::graphics::common::Rect; using namespace ::ndk; namespace aidl::android::hardware::graphics::composer3::vts { class VtsDisplay; /** * A wrapper to IComposerClient. * This wrapper manages the IComposerClient instance and manages the resources for * the tests with respect to the IComposerClient calls. */ class VtsComposerClient { public: VtsComposerClient(const std::string& name); ScopedAStatus createClient(); bool tearDown(ComposerClientWriter*); std::pair getInterfaceVersion() const; std::pair createVirtualDisplay(int32_t width, int32_t height, PixelFormat pixelFormat, int32_t bufferSlotCount); ScopedAStatus destroyVirtualDisplay(int64_t display); std::pair createLayer(int64_t display, int32_t bufferSlotCount, ComposerClientWriter*); ScopedAStatus destroyLayer(int64_t display, int64_t layer, ComposerClientWriter*); std::pair getActiveConfig(int64_t display); ScopedAStatus setActiveConfig(VtsDisplay* vtsDisplay, int32_t config); ScopedAStatus setPeakRefreshRateConfig(VtsDisplay* vtsDisplay); std::pair getDisplayAttribute(int64_t display, int32_t config, DisplayAttribute displayAttribute); ScopedAStatus setPowerMode(int64_t display, PowerMode powerMode); ScopedAStatus setVsync(int64_t display, bool enable); void setVsyncAllowed(bool isAllowed); std::pair> getDataspaceSaturationMatrix(Dataspace dataspace); std::pair> executeCommands( const std::vector& commands); std::optional takeLastVsyncPeriodChangeTimeline(); ScopedAStatus setContentType(int64_t display, ContentType contentType); std::pair setActiveConfigWithConstraints( VtsDisplay* vtsDisplay, int32_t config, const VsyncPeriodChangeConstraints& constraints); std::pair> getDisplayCapabilities( int64_t display); ScopedAStatus dumpDebugInfo(); std::pair getDisplayIdentificationData(int64_t display); std::pair getHdrCapabilities(int64_t display); std::pair> getPerFrameMetadataKeys( int64_t display); std::pair getReadbackBufferAttributes(int64_t display); ScopedAStatus setReadbackBuffer(int64_t display, const native_handle_t* buffer, const ScopedFileDescriptor& releaseFence); std::pair getReadbackBufferFence(int64_t display); std::pair> getColorModes(int64_t display); std::pair> getRenderIntents(int64_t display, ColorMode colorMode); ScopedAStatus setColorMode(int64_t display, ColorMode colorMode, RenderIntent renderIntent); std::pair getDisplayedContentSamplingAttributes(int64_t display); ScopedAStatus setDisplayedContentSamplingEnabled(int64_t display, bool isEnabled, FormatColorComponent formatColorComponent, int64_t maxFrames); std::pair getDisplayedContentSample(int64_t display, int64_t maxFrames, int64_t timestamp); std::pair getDisplayConnectionType(int64_t display); std::pair> getDisplayConfigs(int64_t display); std::pair> getDisplayConfigurations( int64_t display); ScopedAStatus notifyExpectedPresent(int64_t display, ClockMonotonicTimestamp expectedPresentTime, int frameIntervalNs); std::pair getDisplayVsyncPeriod(int64_t display); ScopedAStatus setAutoLowLatencyMode(int64_t display, bool isEnabled); std::pair> getSupportedContentTypes(int64_t display); std::pair> getDisplayDecorationSupport( int64_t display); std::pair getMaxVirtualDisplayCount(); std::pair getDisplayName(int64_t display); ScopedAStatus setClientTargetSlotCount(int64_t display, int32_t bufferSlotCount); std::pair> getCapabilities(); ScopedAStatus setBootDisplayConfig(int64_t display, int32_t config); ScopedAStatus clearBootDisplayConfig(int64_t display); std::pair getPreferredBootDisplayConfig(int64_t display); std::pair> getHdrConversionCapabilities(); std::pair setHdrConversionStrategy( const common::HdrConversionStrategy& conversionStrategy); std::pair getDisplayPhysicalOrientation(int64_t display); ScopedAStatus setIdleTimerEnabled(int64_t display, int32_t timeoutMs); int32_t getVsyncIdleCount(); int64_t getVsyncIdleTime(); int64_t getInvalidDisplayId(); std::pair> getDisplays(); std::pair getOverlaySupport(); ndk::ScopedAStatus setRefreshRateChangedCallbackDebugEnabled(int64_t display, bool enabled); std::vector takeListOfRefreshRateChangedDebugData(); static constexpr int32_t kMaxFrameIntervalNs = 50000000; // 20fps static constexpr int32_t kNoFrameIntervalNs = 0; private: void addDisplayConfigs(VtsDisplay*, const std::vector&); ScopedAStatus addDisplayConfigLegacy(VtsDisplay*, int32_t config); bool getDisplayConfigurationSupported() const; ScopedAStatus updateDisplayProperties(VtsDisplay* vtsDisplay, int32_t config); ScopedAStatus addDisplayToDisplayResources(int64_t display, bool isVirtual); ScopedAStatus addLayerToDisplayResources(int64_t display, int64_t layer); void removeLayerFromDisplayResources(int64_t display, int64_t layer); bool destroyAllLayers(ComposerClientWriter*); bool verifyComposerCallbackParams(); // Keep track of displays and layers. When a test fails/ends, // the VtsComposerClient::tearDown should be called from the // test tearDown to clean up the resources for the test. struct DisplayResource { DisplayResource(bool isVirtual_) : isVirtual(isVirtual_) {} bool isVirtual; std::unordered_set layers; }; std::shared_ptr mComposer; std::shared_ptr mComposerClient; std::shared_ptr mComposerCallback; std::unordered_map mDisplayResources; bool mSupportsBatchedCreateLayer = false; std::atomic mNextLayerHandle = 1; }; class VtsDisplay { public: VtsDisplay(int64_t displayId) : mDisplayId(displayId), mDisplayWidth(0), mDisplayHeight(0) {} int64_t getDisplayId() const { return mDisplayId; } FRect getCrop() const { return {0, 0, static_cast(mDisplayWidth), static_cast(mDisplayHeight)}; } Rect getFrameRect() const { return {0, 0, mDisplayWidth, mDisplayHeight}; } void setDimensions(int32_t displayWidth, int32_t displayHeight) { mDisplayWidth = displayWidth; mDisplayHeight = displayHeight; } int32_t getDisplayWidth() const { return mDisplayWidth; } int32_t getDisplayHeight() const { return mDisplayHeight; } struct DisplayConfig { DisplayConfig(int32_t vsyncPeriod_, int32_t configGroup_, std::optional vrrConfigOpt_ = {}) : vsyncPeriod(vsyncPeriod_), configGroup(configGroup_), vrrConfigOpt(std::move(vrrConfigOpt_)) {} int32_t vsyncPeriod; int32_t configGroup; std::optional vrrConfigOpt; }; void addDisplayConfig(int32_t config, DisplayConfig displayConfig) { mDisplayConfigs.insert({config, displayConfig}); } DisplayConfig getDisplayConfig(int32_t config) { return mDisplayConfigs.find(config)->second; } bool isRateSameBetweenConfigs(int config1, int config2) { const auto displayConfig1 = getDisplayConfig(config1); const auto displayConfig2 = getDisplayConfig(config2); const auto vrrConfigOpt1 = displayConfig1.vrrConfigOpt; const auto vrrConfigOpt2 = displayConfig2.vrrConfigOpt; if (vrrConfigOpt1 && vrrConfigOpt2 && vrrConfigOpt1->minFrameIntervalNs == vrrConfigOpt2->minFrameIntervalNs) { return true; } else if (displayConfig1.vsyncPeriod == displayConfig2.vsyncPeriod) { return true; } return false; } std::string printConfig(int config) { const auto displayConfig = getDisplayConfig(config); const auto vrrConfigOpt = displayConfig.vrrConfigOpt; std::stringstream ss; if (displayConfig.vrrConfigOpt) { ss << "{Config " << config << ": vsyncPeriod " << displayConfig.vsyncPeriod << ", minFrameIntervalNs " << vrrConfigOpt->minFrameIntervalNs << "}"; } else { ss << "{Config " << config << ": vsyncPeriod " << displayConfig.vsyncPeriod << "}"; } return ss.str(); } std::unordered_map getDisplayConfigs() { return mDisplayConfigs; } private: int64_t mDisplayId; int32_t mDisplayWidth; int32_t mDisplayHeight; std::unordered_map mDisplayConfigs; }; } // namespace aidl::android::hardware::graphics::composer3::vts