Merge pull request !16183 from xiaojianfeng/master1021_2
This commit is contained in:
openharmony_ci 2024-10-21 10:39:27 +00:00 committed by Gitee
commit 820f49ee49
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
3 changed files with 781 additions and 0 deletions

View File

@ -0,0 +1,235 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* 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 "gtest/gtest.h"
#include "rs_test_util.h"
#include "surface_buffer_impl.h"
#include "drawable/rs_display_render_node_drawable.h"
#include "pipeline/rs_display_render_node.h"
#include "pipeline/rs_egl_image_manager.h"
#include "pipeline/rs_main_thread.h"
#include "render_context/render_context.h"
using namespace testing;
using namespace testing::ext;
namespace OHOS::Rosen {
class RsEglImageManagerTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
void SetUp() override;
void TearDown() override;
static std::shared_ptr<RenderContext> renderContext_;
static std::shared_ptr<RSEglImageManager> eglImageManager_;
};
std::shared_ptr<RenderContext> RsEglImageManagerTest::renderContext_ = std::make_shared<RenderContext>();
std::shared_ptr<RSEglImageManager> RsEglImageManagerTest::eglImageManager_ = nullptr;
void RsEglImageManagerTest::SetUpTestCase()
{
renderContext_->InitializeEglContext();
renderContext_->SetUpGpuContext();
eglImageManager_ = std::make_shared<RSEglImageManager>(renderContext_->GetEGLDisplay());
}
void RsEglImageManagerTest::TearDownTestCase()
{
renderContext_ = nullptr;
eglImageManager_ = nullptr;
}
void RsEglImageManagerTest::SetUp() {}
void RsEglImageManagerTest::TearDown() {}
/**
* @tc.name: CreateAndShrinkImageCacheFromBuffer01
* @tc.desc: Create valid ImageCache from buffer and shrink it.
* @tc.type: FUNC
* @tc.require: issueI6QHNP
*/
HWTEST_F(RsEglImageManagerTest, CreateAndShrinkImageCacheFromBuffer01, TestSize.Level1)
{
if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR || !RSUniRenderJudgement::IsUniRender()) {
return;
}
NodeId id = 0;
RSDisplayNodeConfig config;
auto node = std::make_shared<RSDisplayRenderNode>(id, config);
node->InitRenderParams();
sptr<IConsumerSurface> consumer = IConsumerSurface::Create("test");
auto displayDrawable =
std::static_pointer_cast<DrawableV2::RSDisplayRenderNodeDrawable>(node->GetRenderDrawable());
auto surfaceHandler = displayDrawable->GetRSSurfaceHandlerOnDraw();
surfaceHandler->SetConsumer(consumer);
sptr<SyncFence> acquireFence = SyncFence::INVALID_FENCE;
int64_t timestamp = 0;
Rect damage;
sptr<OHOS::SurfaceBuffer> buffer = new SurfaceBufferImpl(0);
surfaceHandler->SetBuffer(buffer, acquireFence, damage, timestamp);
ASSERT_NE(node, nullptr);
if (auto displayNode = node->ReinterpretCastTo<RSDisplayRenderNode>()) {
sptr<OHOS::SurfaceBuffer> buffer = surfaceHandler->GetBuffer();
// create image with null fence
auto invalidFenceCache = eglImageManager_->CreateImageCacheFromBuffer(buffer, nullptr);
ASSERT_NE(invalidFenceCache, nullptr);
invalidFenceCache.release();
// create image with valid fence
sptr<SyncFence> acquireFence;
auto validCache = eglImageManager_->CreateImageCacheFromBuffer(buffer, acquireFence);
ASSERT_NE(validCache, nullptr);
validCache.release();
eglImageManager_->ShrinkCachesIfNeeded(true);
// create cache from buffer directly
auto ret = eglImageManager_->CreateImageCacheFromBuffer(buffer, 0);
ASSERT_NE(ret, 0);
eglImageManager_->ShrinkCachesIfNeeded(false);
}
}
/**
* @tc.name: CreateInvalidImageCache01
* @tc.desc: Create invalid cache with invalid egl params.
* @tc.type: FUNC
* @tc.require: issueI6QHNP
*/
HWTEST_F(RsEglImageManagerTest, CreateInvalidImageCache01, TestSize.Level1)
{
std::unique_ptr<ImageCacheSeq> invalidCache =
std::make_unique<ImageCacheSeq>(renderContext_->GetEGLDisplay(), EGL_NO_IMAGE_KHR, nullptr);
auto ret = invalidCache->TextureId();
ASSERT_EQ(ret, 0);
invalidCache.release();
}
/**
* @tc.name: MapEglImageFromSurfaceBuffer01
* @tc.desc: Map egl image from buffer.
* @tc.type: FUNC
* @tc.require: issueI6QHNP
*/
HWTEST_F(RsEglImageManagerTest, MapEglImageFromSurfaceBuffer01, TestSize.Level1)
{
if (RSSystemProperties::GetGpuApiType() == GpuApiType::VULKAN ||
RSSystemProperties::GetGpuApiType() == GpuApiType::DDGR || !RSUniRenderJudgement::IsUniRender()) {
return;
}
NodeId id = 0;
RSDisplayNodeConfig config;
auto node = std::make_shared<RSDisplayRenderNode>(id, config);
node->InitRenderParams();
sptr<IConsumerSurface> consumer = IConsumerSurface::Create("test");
auto displayDrawable =
std::static_pointer_cast<DrawableV2::RSDisplayRenderNodeDrawable>(node->GetRenderDrawable());
auto surfaceHandler = displayDrawable->GetRSSurfaceHandlerOnDraw();
surfaceHandler->SetConsumer(consumer);
sptr<SyncFence> acquireFence = SyncFence::INVALID_FENCE;
int64_t timestamp = 0;
Rect damage;
sptr<OHOS::SurfaceBuffer> buffer = new SurfaceBufferImpl(0);
surfaceHandler->SetBuffer(buffer, acquireFence, damage, timestamp);
ASSERT_NE(node, nullptr);
if (auto displayNode = node->ReinterpretCastTo<RSDisplayRenderNode>()) {
sptr<OHOS::SurfaceBuffer> buffer = surfaceHandler->GetBuffer();
sptr<SyncFence> acquireFence;
auto ret = eglImageManager_->MapEglImageFromSurfaceBuffer(buffer, acquireFence, 0);
ASSERT_NE(ret, 0);
}
}
/**
* @tc.name: ShrinkCachesIfNeeded01
* @tc.desc: Shrink Caches
* @tc.type: FUNC
* @tc.require: issueI7A39J
*/
HWTEST_F(RsEglImageManagerTest, ShrinkCachesIfNeeded01, TestSize.Level1)
{
ASSERT_NE(eglImageManager_, nullptr);
for (size_t i = 0; i <= eglImageManager_->MAX_CACHE_SIZE; i++) {
eglImageManager_->cacheQueue_.push(i);
eglImageManager_->imageCacheSeqs_[i] = nullptr;
}
eglImageManager_->ShrinkCachesIfNeeded(true);
ASSERT_EQ(eglImageManager_->cacheQueue_.size(), eglImageManager_->MAX_CACHE_SIZE);
eglImageManager_->cacheQueue_.push(eglImageManager_->MAX_CACHE_SIZE);
eglImageManager_->imageCacheSeqs_[eglImageManager_->MAX_CACHE_SIZE] = nullptr;
eglImageManager_->ShrinkCachesIfNeeded(false);
ASSERT_EQ(eglImageManager_->cacheQueue_.size(), eglImageManager_->MAX_CACHE_SIZE);
}
/**
* @tc.name: WaitAcquireFence01
* @tc.desc: Wait nullptr acquirefence
* @tc.type: FUNC
* @tc.require: issueI7A39J
*/
HWTEST_F(RsEglImageManagerTest, WaitAcquireFence01, TestSize.Level1)
{
ASSERT_NE(eglImageManager_, nullptr);
eglImageManager_->WaitAcquireFence(nullptr);
}
/**
* @tc.name: ShrinkCachesIfNeeded01
* @tc.desc: UnMap eglImage with invalid seqNum
* @tc.type: FUNC
* @tc.require: issueI7A39J
*/
HWTEST_F(RsEglImageManagerTest, UnMapEglImage01, TestSize.Level1)
{
ASSERT_NE(eglImageManager_, nullptr);
const int invalidSeqNum = -1;
eglImageManager_->UnMapEglImageFromSurfaceBuffer(invalidSeqNum);
eglImageManager_->UnMapEglImageFromSurfaceBufferForUniRedraw(invalidSeqNum);
}
/**
* @tc.name: ImageCacheSeqBindToTexture01
* @tc.desc: Bind to texture
* @tc.type: FUNC
* @tc.require: issueI7A39J
*/
HWTEST_F(RsEglImageManagerTest, ImageCacheSeqBindToTexture01, TestSize.Level1)
{
auto node = RSTestUtil::CreateSurfaceNodeWithBuffer();
auto imageCache = ImageCacheSeq::Create(
renderContext_->GetEGLDisplay(), EGL_NO_CONTEXT, node->GetRSSurfaceHandler()->GetBuffer());
ASSERT_NE(imageCache, nullptr);
ASSERT_EQ(imageCache->BindToTexture(), true);
imageCache->eglImage_ = EGL_NO_IMAGE_KHR;
ASSERT_EQ(imageCache->BindToTexture(), false);
}
/**
* @tc.name: ImageCacheSeqCreate01
* @tc.desc: Create ImageCacheSeq
* @tc.type: FUNC
* @tc.require: issueI7A39J
*/
HWTEST_F(RsEglImageManagerTest, ImageCacheSeqCreate01, TestSize.Level1)
{
auto node = RSTestUtil::CreateSurfaceNodeWithBuffer();
auto imageCache = ImageCacheSeq::Create(EGL_NO_DISPLAY, EGL_NO_IMAGE_KHR, node->GetRSSurfaceHandler()->GetBuffer());
ASSERT_EQ(imageCache, nullptr);
imageCache = ImageCacheSeq::Create(
renderContext_->GetEGLDisplay(), EGL_NO_CONTEXT, node->GetRSSurfaceHandler()->GetBuffer());
ASSERT_NE(imageCache, nullptr);
}
} // namespace OHOS::Rosen

View File

@ -0,0 +1,300 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* 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 <gtest/gtest.h>
#include "pipeline/rs_main_thread.h"
using namespace testing;
using namespace testing::ext;
namespace OHOS {
namespace Rosen {
using ConfigItem = RSGraphicConfig::ConfigItem;
const std::string XML_STR = R"(<?xml version='1.0' encoding="utf-8"?>
<Configs>
<testMap>
<testBooL enable="true"></testBooL>
</testMap>
<testString>testString</testString>
<testStrings>testStrings1 testStrings2 testStrings3</testStrings>
<testInts>1 2 3</testInts>
<testFloats>0.1 0.2 -0.3</testFloats>
<testPositiveFloats>0.1 0.2 0.3</testPositiveFloats>
<testInvalidPositiveFloats>0.1 0.2 -0.3</testInvalidPositiveFloats>
<testUndifined></testUndifined>
</Configs>
)";
const std::string XML_INVALID_INPUT_STR = R"(<?xml version='1.0' encoding="utf-8"?>
<Configs>
<testMap>
<testBooL></testBooL>
</testMap>
<testString></testString>
<testStrings></testStrings>
<testInts>a b c</testInts>
<testFloats>a b c</testFloats>
<testPositiveFloats>a b c</testPositiveFloats>
</Configs>
)";
class RsGraphicConfigTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
void SetUp() override;
void TearDown() override;
ConfigItem ReadConfig(const std::string& xmlStr);
};
void RsGraphicConfigTest::SetUpTestCase() {}
void RsGraphicConfigTest::TearDownTestCase() {}
void RsGraphicConfigTest::SetUp() {}
void RsGraphicConfigTest::TearDown() {}
void SetConfigMap(std::map<std::string, RSGraphicConfig::ValueType>* nonConstConfigMap)
{
*nonConstConfigMap = {
{ "testMap", RSGraphicConfig::ValueType::MAP },
{ "testBooL", RSGraphicConfig::ValueType::UNDIFINED },
{ "testString", RSGraphicConfig::ValueType::STRING },
{ "testStrings", RSGraphicConfig::ValueType::STRINGS },
{ "testInts", RSGraphicConfig::ValueType::INTS },
{ "testFloats", RSGraphicConfig::ValueType::FLOATS },
{ "testPositiveFloats", RSGraphicConfig::ValueType::POSITIVE_FLOATS },
{ "testInvalidPositiveFloats", RSGraphicConfig::ValueType::POSITIVE_FLOATS },
{ "testUndifined", RSGraphicConfig::ValueType::UNDIFINED },
};
}
void ResetConfigMap(std::map<std::string, RSGraphicConfig::ValueType>* nonConstConfigMap)
{
*nonConstConfigMap = {
{ "blurEffect", RSGraphicConfig::ValueType::MAP },
{ "blurSwitchOpen", RSGraphicConfig::ValueType::UNDIFINED },
};
}
ConfigItem RsGraphicConfigTest::ReadConfig(const std::string& xmlStr)
{
ConfigItem config;
xmlDocPtr docPtr = xmlParseMemory(xmlStr.c_str(), xmlStr.length() + 1);
if (docPtr == nullptr) {
return config;
}
xmlNodePtr rootPtr = xmlDocGetRootElement(docPtr);
if (rootPtr == nullptr || rootPtr->name == nullptr ||
xmlStrcmp(rootPtr->name, reinterpret_cast<const xmlChar*>("Configs"))) {
xmlFreeDoc(docPtr);
return config;
}
std::map<std::string, ConfigItem> configMap;
config.SetValue(configMap);
RSGraphicConfig::ReadConfig(rootPtr, *config.mapValue);
xmlFreeDoc(docPtr);
return config;
}
namespace {
/* *
* @tc.name: LoadConfigXml
* @tc.desc: test LoadConfigXml.
* @tc.type: FUNC
*/
HWTEST_F(RsGraphicConfigTest, LoadConfigXml, TestSize.Level2)
{
ASSERT_TRUE(RSGraphicConfig::LoadConfigXml());
}
/* *
* @tc.name: ReadConfig
* @tc.desc: test ReadConfig.
* @tc.type: FUNC
*/
HWTEST_F(RsGraphicConfigTest, ReadConfig, TestSize.Level2)
{
auto nonConstConfigMap =
const_cast<std::map<std::string, RSGraphicConfig::ValueType>*>(&RSGraphicConfig::configItemTypeMap_);
SetConfigMap(nonConstConfigMap);
RSGraphicConfig::config_ = ReadConfig(XML_STR);
RSGraphicConfig::ConfigItem item = RSGraphicConfig::config_["testMap"];
ASSERT_TRUE(item.IsMap());
item = RSGraphicConfig::config_["testMap"]["testBooL"].GetProp("enable");
ASSERT_TRUE(item.boolValue);
ASSERT_TRUE(item.IsBool());
item = RSGraphicConfig::config_["testString"];
ASSERT_EQ("testString", item.stringValue);
ASSERT_TRUE(item.IsString());
item = RSGraphicConfig::config_["testStrings"];
ASSERT_TRUE(item.IsStrings());
ASSERT_TRUE(item.stringsValue->size() == 3);
auto stringValues = *item.stringsValue;
ASSERT_EQ("testStrings1", stringValues[0]);
ASSERT_EQ("testStrings2", stringValues[1]);
ASSERT_EQ("testStrings3", stringValues[2]);
item = RSGraphicConfig::config_["testFloats"];
ASSERT_TRUE(item.IsFloats());
ASSERT_TRUE(item.floatsValue->size() == 3);
auto floatValues = *item.floatsValue;
ASSERT_TRUE(std::abs(0.1 - floatValues[0]) < std::numeric_limits<float>::epsilon());
ASSERT_TRUE(std::abs(0.2 - floatValues[1]) < std::numeric_limits<float>::epsilon());
ASSERT_TRUE(std::abs(-0.3 - floatValues[2]) < std::numeric_limits<float>::epsilon());
item = RSGraphicConfig::config_["testInts"];
ASSERT_TRUE(item.IsInts());
ASSERT_TRUE(item.intsValue->size() == 3);
auto intValues = *item.intsValue;
ASSERT_EQ(1, intValues[0]);
ASSERT_EQ(2, intValues[1]);
ASSERT_EQ(3, intValues[2]);
item = RSGraphicConfig::config_["testPositiveFloats"];
ASSERT_TRUE(item.IsFloats());
ASSERT_TRUE(item.floatsValue->size() == 3);
floatValues = *item.floatsValue;
ASSERT_TRUE(std::abs(0.1 - floatValues[0]) < std::numeric_limits<float>::epsilon());
ASSERT_TRUE(std::abs(0.2 - floatValues[1]) < std::numeric_limits<float>::epsilon());
ASSERT_TRUE(std::abs(0.3 - floatValues[2]) < std::numeric_limits<float>::epsilon());
item = RSGraphicConfig::config_["testInvalidPositiveFloats"];
ASSERT_TRUE(item.IsFloats());
ASSERT_TRUE(item.floatsValue->size() == 0);
item = RSGraphicConfig::config_["testUndifined"];
ASSERT_TRUE(item.type == RSBaseXmlConfig::ValueType::UNDIFINED);
ResetConfigMap(nonConstConfigMap);
}
/* *
* @tc.name: ReadConfig01
* @tc.desc: test ReadConfig invalid value input.
* @tc.type: FUNC
*/
HWTEST_F(RsGraphicConfigTest, ReadConfig01, TestSize.Level2)
{
auto nonConstConfigMap =
const_cast<std::map<std::string, RSGraphicConfig::ValueType>*>(&RSGraphicConfig::configItemTypeMap_);
SetConfigMap(nonConstConfigMap);
RSGraphicConfig::config_ = ReadConfig(XML_INVALID_INPUT_STR);
RSGraphicConfig::ConfigItem item = RSGraphicConfig::config_["testMap"];
ASSERT_TRUE(item.IsMap());
item = RSGraphicConfig::config_["testMap"]["testBooL"].GetProp("enable");
ASSERT_FALSE(item.IsBool());
item = RSGraphicConfig::config_["testString"];
ASSERT_TRUE(item.IsString());
ASSERT_EQ("", item.stringValue);
item = RSGraphicConfig::config_["testStrings"];
ASSERT_TRUE(item.IsStrings());
ASSERT_TRUE(item.stringsValue->size() == 0);
item = RSGraphicConfig::config_["testInts"];
ASSERT_TRUE(item.IsInts());
ASSERT_TRUE(item.intsValue->size() == 0);
item = RSGraphicConfig::config_["testFloats"];
ASSERT_TRUE(item.IsFloats());
ASSERT_TRUE(item.floatsValue->size() == 0);
item = RSGraphicConfig::config_["testPositiveFloats"];
ASSERT_TRUE(item.IsFloats());
ASSERT_TRUE(item.floatsValue->size() == 0);
ResetConfigMap(nonConstConfigMap);
}
/* *
* @tc.name: DumpConfig01
* @tc.desc: test DumpConfig.
* @tc.type: FUNC
*/
HWTEST_F(RsGraphicConfigTest, DumpConfig01, TestSize.Level2)
{
std::string xmlStr = "<?xml version='1.0' encoding=\"utf-8\"?>"
"<Configs>"
"<blurEffect>"
"<blurSwitchOpen enable=\"true\"></blurSwitchOpen>"
"</blurEffect>"
"</Configs>";
RSGraphicConfig::config_ = ReadConfig(xmlStr);
RSGraphicConfig::DumpConfig(*RSGraphicConfig::GetConfig().mapValue);
}
/* *
* @tc.name: ReadProperty01
* @tc.desc: test ReadProperty name and enable.
* @tc.type: FUNC
*/
HWTEST_F(RsGraphicConfigTest, ReadProperty01, TestSize.Level2)
{
std::string xmlStr = "<?xml version='1.0' encoding=\"utf-8\"?>"
"<Configs>"
"<blurEffect>"
"<blurSwitchOpen name=\"testName\" enable=\"true\"></blurSwitchOpen>"
"</blurEffect>"
"</Configs>";
RSGraphicConfig::config_ = ReadConfig(xmlStr);
}
/* *
* @tc.name: BlurEffectConfig01
* @tc.desc: set blurEffect.blurSwitchOpen true.
* @tc.type: FUNC
*/
HWTEST_F(RsGraphicConfigTest, BlurEffectConfig01, TestSize.Level2)
{
std::string xmlStr = "<?xml version='1.0' encoding=\"utf-8\"?>"
"<Configs>"
"<blurEffect>"
"<blurSwitchOpen enable=\"true\"></blurSwitchOpen>"
"</blurEffect>"
"</Configs>";
RSGraphicConfig::config_ = ReadConfig(xmlStr);
RSMainThread::Instance()->ConfigureRenderService();
ASSERT_TRUE(RSMainThread::Instance()->IsBlurSwitchOpen());
}
/* *
* @tc.name: BlurEffectConfig02
* @tc.desc: set blurEffect.blurSwitchOpen false.
* @tc.type: FUNC
*/
HWTEST_F(RsGraphicConfigTest, BlurEffectConfig02, TestSize.Level2)
{
std::string xmlStr = "<?xml version='1.0' encoding=\"utf-8\"?>"
"<Configs>"
"<blurEffect>"
"<blurSwitchOpen enable=\"false\"></blurSwitchOpen>"
"</blurEffect>"
"</Configs>";
RSGraphicConfig::config_ = ReadConfig(xmlStr);
RSMainThread::Instance()->ConfigureRenderService();
ASSERT_FALSE(RSMainThread::Instance()->IsBlurSwitchOpen());
}
} // namespace
} // namespace Rosen
} // namespace OHOS

View File

@ -0,0 +1,246 @@
/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* 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, Hardware
* 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 "gtest/gtest.h"
#include "pipeline/rs_hardware_thread.h"
#include "pipeline/rs_uni_render_composer_adapter.h"
#include "rs_test_util.h"
#include "pipeline/rs_uni_render_engine.h"
#include "mock/mock_hdi_device.h"
using namespace testing;
using namespace testing::ext;
namespace {
const int DEFAULT_WIDTH = 2160;
const int DEFAULT_HEIGHT = 1080;
};
namespace OHOS::Rosen {
class RsHardwareThreadTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
void SetUp() override;
void TearDown() override;
void CreateComposerAdapterWithScreenInfo(uint32_t width = 2560, uint32_t height = 1080,
ScreenColorGamut colorGamut = ScreenColorGamut::COLOR_GAMUT_SRGB,
ScreenState state = ScreenState::UNKNOWN,
ScreenRotation rotation = ScreenRotation::ROTATION_0);
public:
std::unique_ptr<RSComposerAdapter> composerAdapter_;
sptr<OHOS::Rosen::RSScreenManager> screenManager_;
int32_t offsetX = 0; // screenOffset on x axis equals to 0
int32_t offsetY = 0; // screenOffset on y axis equals to 0
float mirrorAdaptiveCoefficient = 1.0f;
uint32_t screenId_ = 10;
static inline BufferRequestConfig requestConfig = {
.width = 0x100,
.height = 0x100,
.strideAlignment = 0x8,
.format = GRAPHIC_PIXEL_FMT_RGBA_8888,
.usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA,
.timeout = 0,
};
static inline BufferFlushConfig flushConfig = {
.damage = { .w = 0x100, .h = 0x100, },
};
static inline Mock::HdiDeviceMock* hdiDeviceMock_;
};
void RsHardwareThreadTest::SetUpTestCase()
{
hdiDeviceMock_ = Mock::HdiDeviceMock::GetInstance();
EXPECT_CALL(*hdiDeviceMock_, RegHotPlugCallback(_, _)).WillRepeatedly(testing::Return(0));
EXPECT_CALL(*hdiDeviceMock_, RegHwcDeadCallback(_, _)).WillRepeatedly(testing::Return(false));
EXPECT_CALL(*hdiDeviceMock_, PrepareScreenLayers(_, _)).WillRepeatedly(testing::Return(0));
EXPECT_CALL(*hdiDeviceMock_, GetScreenCompChange(_, _, _)).WillRepeatedly(testing::Return(0));
EXPECT_CALL(*hdiDeviceMock_, Commit(_, _)).WillRepeatedly(testing::Return(0));
RSTestUtil::InitRenderNodeGC();
}
void RsHardwareThreadTest::TearDownTestCase() {}
void RsHardwareThreadTest::TearDown()
{
screenManager_ = OHOS::Rosen::impl::RSScreenManager::GetInstance();
OHOS::Rosen::impl::RSScreenManager& screenManager =
static_cast<OHOS::Rosen::impl::RSScreenManager&>(*screenManager_);
screenManager.screens_.erase(screenId_);
}
void RsHardwareThreadTest::SetUp()
{
screenManager_ = OHOS::Rosen::impl::RSScreenManager::GetInstance();
std::unique_ptr<impl::RSScreen> rsScreen =
std::make_unique<impl::RSScreen>(screenId_, true, HdiOutput::CreateHdiOutput(screenId_), nullptr);
screenId_ = rsScreen->Id();
screenManager_->MockHdiScreenConnected(rsScreen);
CreateComposerAdapterWithScreenInfo(DEFAULT_WIDTH, DEFAULT_HEIGHT,
ScreenColorGamut::COLOR_GAMUT_SRGB, ScreenState::UNKNOWN, ScreenRotation::ROTATION_0);
auto mainThread = RSMainThread::Instance();
if (mainThread->rsVSyncDistributor_ == nullptr) {
auto vsyncGenerator = CreateVSyncGenerator();
auto vsyncController = new VSyncController(vsyncGenerator, 0);
mainThread->rsVSyncDistributor_ = new VSyncDistributor(vsyncController, "rs");
vsyncGenerator->SetRSDistributor(mainThread->rsVSyncDistributor_);
}
}
void RsHardwareThreadTest::CreateComposerAdapterWithScreenInfo(uint32_t width, uint32_t height,
ScreenColorGamut colorGamut, ScreenState state, ScreenRotation rotation)
{
auto info = screenManager_->QueryScreenInfo(screenId_);
info.phyWidth = width;
info.phyHeight = height;
info.colorGamut = colorGamut;
info.width = width;
info.height = height;
info.state = state;
info.rotation = rotation;
composerAdapter_ = std::make_unique<RSComposerAdapter>();
composerAdapter_->Init(info, offsetX, offsetY, mirrorAdaptiveCoefficient, nullptr);
composerAdapter_->SetHdiBackendDevice(hdiDeviceMock_);
}
/**
* @tc.name: ClearFrameBuffers01
* @tc.desc: Test RsHardwareThreadTest.ClearFrameBuffers
* @tc.type: FUNC
* @tc.require: issueI6R49K
*/
HWTEST_F(RsHardwareThreadTest, ClearFrameBuffers01, TestSize.Level1)
{
auto& hardwareThread = RSHardwareThread::Instance();
auto hdiOutput = HdiOutput::CreateHdiOutput(screenId_);
if (hdiOutput->GetFrameBufferSurface()) {
GSError ret = hardwareThread.ClearFrameBuffers(hdiOutput);
ASSERT_EQ(ret, GSERROR_OK);
}
}
/**
* @tc.name: Start01
* @tc.desc: Test RsHardwareThreadTest.Start
* @tc.type: FUNC
* @tc.require: issueI6R49K
*/
HWTEST_F(RsHardwareThreadTest, Start01, TestSize.Level1)
{
auto& hardwareThread = RSHardwareThread::Instance();
hardwareThread.Start();
ASSERT_NE(hardwareThread.hdiBackend_, nullptr);
}
/**
* @tc.name: Start02
* @tc.desc: Test RsHardwareThreadTest.PostTask
* @tc.type: FUNC
* @tc.require: issueI6R49K
*/
HWTEST_F(RsHardwareThreadTest, Start02, TestSize.Level1)
{
auto& hardwareThread = RSHardwareThread::Instance();
hardwareThread.PostTask([&]() {});
hardwareThread.Start();
ASSERT_NE(hardwareThread.hdiBackend_, nullptr);
hardwareThread.PostTask([&]() {});
hardwareThread.ScheduleTask([=]() {}).wait();
}
/**
* @tc.name: Start03
* @tc.desc: Test RsHardwareThreadTest.CommitAndReleaseLayers
* @tc.type: FUNC
* @tc.require: issueI6R49K
*/
HWTEST_F(RsHardwareThreadTest, Start03, TestSize.Level1)
{
auto& hardwareThread = RSHardwareThread::Instance();
hardwareThread.Start();
SetUp();
auto surfaceNode1 = RSTestUtil::CreateSurfaceNodeWithBuffer();
auto surfaceNode2 = RSTestUtil::CreateSurfaceNodeWithBuffer();
auto surfaceNode3 = RSTestUtil::CreateSurfaceNodeWithBuffer();
RectI dstRect{0, 0, 400, 600};
surfaceNode1->SetSrcRect(dstRect);
surfaceNode1->SetDstRect(dstRect);
surfaceNode2->SetSrcRect(dstRect);
surfaceNode2->SetDstRect(dstRect);
surfaceNode3->SetSrcRect(dstRect);
surfaceNode3->SetDstRect(dstRect);
auto layer1 = composerAdapter_->CreateLayer(*surfaceNode1);
ASSERT_NE(layer1, nullptr);
auto layer2 = composerAdapter_->CreateLayer(*surfaceNode2);
ASSERT_NE(layer2, nullptr);
auto layer3 = composerAdapter_->CreateLayer(*surfaceNode3);
ASSERT_NE(layer3, nullptr);
std::vector<LayerInfoPtr> layers;
layers.emplace_back(layer1);
layers.emplace_back(layer2);
layers.emplace_back(layer3);
auto& uniRenderThread = RSUniRenderThread::Instance();
uniRenderThread.Sync(std::make_unique<RSRenderThreadParams>());
hardwareThread.CommitAndReleaseLayers(composerAdapter_->output_, layers);
}
/**
* @tc.name: Start04
* @tc.desc: Test RsHardwareThreadTest.ReleaseBuffer
* @tc.type: FUNC
* @tc.require: issueI6R49K
*/
HWTEST_F(RsHardwareThreadTest, Start04, TestSize.Level1)
{
auto rsSurfaceRenderNode = RSTestUtil::CreateSurfaceNode();
const auto& surfaceConsumer = rsSurfaceRenderNode->GetRSSurfaceHandler()->GetConsumer();
auto producer = surfaceConsumer->GetProducer();
sptr<Surface> sProducer = Surface::CreateSurfaceAsProducer(producer);
sProducer->SetQueueSize(1);
sptr<SurfaceBuffer> buffer;
sptr<SyncFence> requestFence = SyncFence::INVALID_FENCE;
GSError ret = sProducer->RequestBuffer(buffer, requestFence, requestConfig);
ASSERT_EQ(ret, GSERROR_OK);
sptr<SyncFence> flushFence = SyncFence::INVALID_FENCE;
ret = sProducer->FlushBuffer(buffer, flushFence, flushConfig);
ASSERT_EQ(ret, GSERROR_OK);
OHOS::sptr<SurfaceBuffer> cbuffer;
Rect damage;
sptr<SyncFence> acquireFence = SyncFence::INVALID_FENCE;
int64_t timestamp = 0;
ret = surfaceConsumer->AcquireBuffer(cbuffer, acquireFence, timestamp, damage);
ASSERT_EQ(ret, GSERROR_OK);
}
/**
* @tc.name: ClearFrameBuffers02
* @tc.desc: Test RsHardwareThreadTest.ClearFrameBuffers
* @tc.type: FUNC
* @tc.require: issueI6R49K
*/
HWTEST_F(RsHardwareThreadTest, ClearFrameBuffers02, TestSize.Level1)
{
auto& hardwareThread = RSHardwareThread::Instance();
GSError ret = hardwareThread.ClearFrameBuffers(nullptr);
ASSERT_EQ(ret, GSERROR_INVALID_ARGUMENTS);
auto hdiOutput = HdiOutput::CreateHdiOutput(screenId_);
if (hdiOutput->GetFrameBufferSurface()) {
GSError ret = hardwareThread.ClearFrameBuffers(hdiOutput);
ASSERT_EQ(ret, GSERROR_OK);
}
}
} // namespace OHOS::Rosen